server.c (1723B)
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 freeaddrinfo(ai); 51 if (!p) { 52 logwarnx("failed to bind socket"); 53 return -1; 54 } 55 return listenfd; 56 } 57 58 int 59 serveraccept(int listenfd) 60 { 61 struct sockaddr_storage remote; 62 int netfd; 63 64 netfd = accept(listenfd, (struct sockaddr *)&remote, 65 (socklen_t []){sizeof(remote)}); 66 if (netfd < 0) { 67 if (errno != ECONNABORTED) 68 logwarn("accept"); 69 return -1; 70 } 71 72 setnonblock(netfd, 1); 73 setsockopt(netfd, SOL_SOCKET, SO_KEEPALIVE, (int []){1}, sizeof(int)); 74 setsockopt(netfd, IPPROTO_TCP, TCP_NODELAY, (int []){1}, sizeof(int)); 75 76 if (challenge(netfd) < 0 || response(netfd) < 0) { 77 close(netfd); 78 logwarnx("challenge-response failed"); 79 return -1; 80 } 81 return netfd; 82 }