server.c (1705B)
1 #include <sys/types.h> 2 #include <sys/socket.h> 3 4 #include <netinet/in.h> 5 #include <netinet/tcp.h> 6 #include <arpa/inet.h> 7 #include <netdb.h> 8 9 #include <errno.h> 10 #include <stdint.h> 11 #include <string.h> 12 #include <unistd.h> 13 14 #include "warp.h" 15 16 int 17 serverinit(char *host, char *port) 18 { 19 struct addrinfo hints, *ai, *p; 20 int ret, listenfd; 21 22 memset(&hints, 0, sizeof(hints)); 23 hints.ai_family = AF_UNSPEC; 24 hints.ai_socktype = SOCK_STREAM; 25 hints.ai_flags = AI_PASSIVE; 26 27 if ((ret = getaddrinfo(host, port, &hints, &ai))) { 28 logwarnx("getaddrinfo: %s", gai_strerror(ret)); 29 return -1; 30 } 31 32 for (p = ai; p; p = p->ai_next) { 33 if (p->ai_family != aftype) 34 continue; 35 if ((listenfd = socket(p->ai_family, p->ai_socktype, 36 p->ai_protocol)) < 0) 37 continue; 38 setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (int []){1}, 39 sizeof(int)); 40 if (bind(listenfd, p->ai_addr, p->ai_addrlen) < 0) { 41 close(listenfd); 42 continue; 43 } 44 if (listen(listenfd, 5) < 0) { 45 close(listenfd); 46 continue; 47 } 48 break; 49 } 50 if (!p) 51 logwarnx("failed to bind socket"); 52 freeaddrinfo(ai); 53 return listenfd; 54 } 55 56 int 57 serveraccept(int listenfd) 58 { 59 struct sockaddr_storage remote; 60 int netfd; 61 62 netfd = accept(listenfd, (struct sockaddr *)&remote, 63 (socklen_t []){sizeof(remote)}); 64 if (netfd < 0) { 65 if (errno != ECONNABORTED) 66 logwarn("accept"); 67 return -1; 68 } 69 70 setnonblock(netfd, 1); 71 setsockopt(netfd, SOL_SOCKET, SO_KEEPALIVE, (int []){1}, sizeof(int)); 72 setsockopt(netfd, IPPROTO_TCP, TCP_NODELAY, (int []){1}, sizeof(int)); 73 74 if (challenge(netfd) < 0 || response(netfd) < 0) { 75 close(netfd); 76 logwarnx("challenge-response failed"); 77 return -1; 78 } 79 return netfd; 80 }