stun

simple point to point tunnel
git clone git://git.2f30.org/stun
Log | Files | Refs | README

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 }