stun

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

client.c (1214B)


      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 <string.h>
     10 #include <unistd.h>
     11 
     12 #include "warp.h"
     13 
     14 int
     15 clientconnect(char *host, char *port)
     16 {
     17 	struct addrinfo hints, *ai, *p;
     18 	int ret, netfd;
     19 
     20 	memset(&hints, 0, sizeof(hints));
     21 	hints.ai_family = AF_UNSPEC;
     22 	hints.ai_socktype = SOCK_STREAM;
     23 	if ((ret = getaddrinfo(host, port, &hints, &ai))) {
     24 		logwarnx("getaddrinfo: %s", gai_strerror(ret));
     25 		return -1;
     26 	}
     27 
     28 	for (p = ai; p; p = p->ai_next) {
     29 		if (p->ai_family != aftype)
     30 			continue;
     31 		if ((netfd = socket(p->ai_family, p->ai_socktype,
     32 		                    p->ai_protocol)) < 0)
     33 			continue;
     34 		if (connect(netfd, p->ai_addr, p->ai_addrlen) < 0) {
     35 			close(netfd);
     36 			continue;
     37 		}
     38 		break;
     39 	}
     40 	freeaddrinfo(ai);
     41 	if (!p) {
     42 		logwarnx("failed to connect to %s:%s", host, port);
     43 		return -1;
     44 	}
     45 
     46 	setnonblock(netfd, 1);
     47 	setsockopt(netfd, SOL_SOCKET, SO_KEEPALIVE, (int []){1}, sizeof(int));
     48 	setsockopt(netfd, IPPROTO_TCP, TCP_NODELAY, (int []){1}, sizeof(int));
     49 
     50 	if (response(netfd) < 0 || challenge(netfd) < 0) {
     51 		close(netfd);
     52 		logwarnx("challenge-response failed");
     53 		return -1;
     54 	}
     55 	return netfd;
     56 }