warp-vpn

point to point VPN implementation
git clone git://git.2f30.org/warp-vpn
Log | Files | Refs | README

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 }