From d634237ed596eb8c50574747b71aea74f12b9fa1 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Thu, 28 Jul 2011 19:23:25 +0200 Subject: [PATCH] new optional ipv4 only code, to get rid of the getaddrinfo and gai_* crap, which pulls in a helluva lot of dependencies --- rocksockserver.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/rocksockserver.c b/rocksockserver.c index 63721d9..6c25009 100644 --- a/rocksockserver.c +++ b/rocksockserver.c @@ -19,8 +19,6 @@ #include #include -// rocksock.h only needed for struct rs_hostInfo -#include "rocksock.h" #include "rocksockserver.h" #include "endianness.h" @@ -29,6 +27,16 @@ #include "../lib/include/strlib.h" #include "../lib/include/stringptr.h" +typedef struct { + char* host; + unsigned short port; +#ifndef IPV4_ONLY + struct addrinfo* hostaddr; +#else + struct sockaddr_in hostaddr; +#endif +} rs_hostInfo; + int microsleep(long microsecs) { struct timespec req, rem; req.tv_sec = microsecs / 1000000; @@ -38,12 +46,29 @@ int microsleep(long microsecs) { return ret; } +#ifdef IPV4_ONLY +static void ipv4fromstring(char* ipstring, unsigned char* fourbytesptr) { + char* start = ipstring; + size_t outbyte = 0; + while(outbyte < 4) { + if(*ipstring == '.' || !*ipstring) { + fourbytesptr[outbyte] = strtoint(start, ipstring - start); + start = ipstring + 1; + outbyte++; + } + ipstring++; + } +} +#endif + int rocksockserver_resolve_host(rs_hostInfo* hostinfo) { - struct addrinfo hints; - int ret; + if (!hostinfo || !hostinfo->host || !hostinfo->port) return -1; +#ifndef IPV4_ONLY char pbuf[8]; char* ports; - if (!hostinfo || !hostinfo->host || !hostinfo->port) return -1; + int ret; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -57,12 +82,18 @@ int rocksockserver_resolve_host(rs_hostInfo* hostinfo) { log_put(1, VARISL("error resolving: "), VARICC(gai_strerror(ret)), NULL); return ret; } +#else + memset(&hostinfo->hostaddr, 0, sizeof(struct sockaddr_in)); + ipv4fromstring(hostinfo->host, (unsigned char*) &hostinfo->hostaddr.sin_addr); + hostinfo->hostaddr.sin_family = AF_INET; + hostinfo->hostaddr.sin_port = htons(hostinfo->port); + return 0; +#endif } int rocksockserver_init(rocksockserver* srv, char* listenip, unsigned short port, void* userdata) { int ret = 0; int yes = 1; - struct addrinfo* p; rs_hostInfo conn; if(!srv || !listenip || !port) return -1; conn.host = listenip; @@ -72,6 +103,8 @@ int rocksockserver_init(rocksockserver* srv, char* listenip, unsigned short port srv->sleeptime_us = 20000; // set a reasonable default value. it's a compromise between throughput and cpu usage basically. ret = rocksockserver_resolve_host(&conn); if(ret) return ret; +#ifndef IPV4_ONLY + struct addrinfo* p; for(p = conn.hostaddr; p != NULL; p = p->ai_next) { srv->listensocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (srv->listensocket < 0) { @@ -93,6 +126,20 @@ int rocksockserver_init(rocksockserver* srv, char* listenip, unsigned short port ret = -1; } freeaddrinfo(conn.hostaddr); +#else + srv->listensocket = socket(AF_INET, SOCK_STREAM, 0); + if(srv->listensocket < 0) { + log_perror("socket"); + return -1; + } + setsockopt(srv->listensocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + if(bind(srv->listensocket, (struct sockaddr*) &conn.hostaddr, sizeof(struct sockaddr_in)) < 0) { + close(srv->listensocket); + log_perror("bind"); + return -1; + } + +#endif // listen if (listen(srv->listensocket, 10) == -1) { log_perror("listen"); -- 2.11.4.GIT