From: John Hodge Date: Sun, 27 May 2012 10:27:00 +0000 (+0800) Subject: Usermode/libpsocket - Heaps of work on getaddrinfo X-Git-Tag: rel0.15~611^2~66 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=8d2115456c8c70e6c73d713853a8c32826543601;p=tpg%2Facess2.git Usermode/libpsocket - Heaps of work on getaddrinfo --- diff --git a/Usermode/Libraries/libpsocket.so_src/Makefile b/Usermode/Libraries/libpsocket.so_src/Makefile index ee0b5795..81418ad7 100644 --- a/Usermode/Libraries/libpsocket.so_src/Makefile +++ b/Usermode/Libraries/libpsocket.so_src/Makefile @@ -4,7 +4,7 @@ include ../Makefile.cfg CPPFLAGS += CFLAGS += -Wall -LDFLAGS += -lc -soname libpsocket.so +LDFLAGS += -lc -soname libpsocket.so -lnet OBJ = main.o getaddrinfo.o socket.o BIN = libpsocket.so diff --git a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c index e122a5aa..57120f0d 100644 --- a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c +++ b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c @@ -7,19 +7,118 @@ */ #include #include +#include // Net_ParseAddress +#include // malloc +#include // memcpy +#include // === CODE === int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { - static struct addrinfo info; - static struct sockaddr_in addr; + static const struct addrinfo defhints = {.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG}; + struct addrinfo *ret = NULL; - addr.sin_family = 4; - addr.sin_addr.s_addr = 0x2701A8C0; - info.ai_family = 4; - info.ai_addr = (struct sockaddr *) &addr; + // Error checks + if( !node && !service ) return EAI_NONAME; + + if( !hints ) + hints = &defhints; + + if( !node ) + { + if( !(hints->ai_flags & AI_PASSIVE) ) + ; // Use localhost + else + ; // Use wildcard + } + else + { + // 1. Check if the node is an IP address + // TODO: Break this function out into inet_pton? + { + int type; + char addrdata[16]; + type = Net_ParseAddress(node, addrdata); + switch(type) + { + case 0: + break; + case 4: // IPv4 + ret = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + ret->ai_family = AF_INET; + ret->ai_socktype = 0; + ret->ai_protocol = 0; + ret->ai_addrlen = sizeof(struct in_addr); + ret->ai_addr = (void*)( ret + 1 ); + ret->ai_canonname = 0; + ret->ai_next = 0; + ((struct sockaddr_in*)ret->ai_addr)->sin_family = AF_INET; + ((struct sockaddr_in*)ret->ai_addr)->sin_port = 0; + memcpy( &((struct sockaddr_in*)ret->ai_addr)->sin_addr, addrdata, 4 ); + break; + default: + _SysDebug("getaddrinfo: Unknown address family %i", type); + return 1; + } + } + + // 2. Check for a DNS name + // - No luck with above, and hints->ai_flags doesn't have AI_NUMERICHOST set + if( !ret && !(hints->ai_flags & AI_NUMERICHOST) ) + { + // TODO: DNS Lookups + // ? /Acess/Conf/Nameservers + // ? /Acess/Conf/Hosts + } + + // 3. No Match, chuck sad + if( !ret ) + { + return EAI_NONAME; + } + } + + int default_socktype = 0; + int default_protocol = 0; + int default_port = 0; + + // Convert `node` into types + if( service ) + { + // TODO: Read something like /Acess/Conf/services + } + + struct addrinfo *ai; + for( ai = ret; ai; ai = ai->ai_next) + { + struct sockaddr_in *in = (void*)ai->ai_addr; + struct sockaddr_in6 *in6 = (void*)ai->ai_addr; + + // Check ai_socktype/ai_protocol + // TODO: Do both of these need to be zero for defaults to apply? + if( ai->ai_socktype == 0 ) + ai->ai_socktype = default_socktype; + if( ai->ai_protocol == 0 ) + ai->ai_protocol = default_protocol; + + switch(ai->ai_family) + { + case AF_INET: + if( in->sin_port == 0 ) + in->sin_port = default_port; + break; + case AF_INET6: + if( in6->sin6_port == 0 ) + in6->sin6_port = default_port; + break; + default: + _SysDebug("getaddrinfo: Unknown address family %i (setting port)", ai->ai_family); + return 1; + } + } - return 1; + *res = ret; + return 0; } void freeaddrinfo(struct addrinfo *res) @@ -31,8 +130,8 @@ const char *gai_strerror(int errnum) { switch(errnum) { - case 0: return "No error"; - case 1: return "Unimplemented"; + case EAI_SUCCESS: return "No error"; + case EAI_FAIL: return "Permanent resolution failure"; default: return "UNKNOWN"; } } diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h index cea819c5..e9cf7883 100644 --- a/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h +++ b/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h @@ -1,7 +1,29 @@ #ifndef _LIBPSOCKET__NETDB_H_ #define _LIBPSOCKET__NETDB_H_ -typedef unsigned int socklen_t; +#include + +#define AI_PASSIVE 0x001 +#define AI_V4MAPPED 0x002 +#define AI_ADDRCONFIG 0x004 +#define AI_NUMERICHOST 0x008 + +enum +{ + EAI_SUCCESS, + EAI_AGAIN, + EAI_BADFLAGS, + EAI_FAMILY, + EAI_SOCKTTPE, + + EAI_ADDRFAMILY, + EAI_FAIL, + EAI_MEMORY, + EAI_NODATA, + EAI_NONAME, + EAI_SERVICE, + EAI_SYSTEM +}; struct addrinfo { diff --git a/Usermode/Libraries/libpsocket.so_src/main.c b/Usermode/Libraries/libpsocket.so_src/main.c index 09b39879..99fbe2ae 100644 --- a/Usermode/Libraries/libpsocket.so_src/main.c +++ b/Usermode/Libraries/libpsocket.so_src/main.c @@ -5,9 +5,28 @@ * main.c * - Entrypoint and misc code */ +#include +#include +#include int SoMain(void) { return 0; } +char *mkstr(const char *format, ...) +{ + va_list args; + int len; + char *ret; + + va_start(args, format); + len = vsnprintf(NULL, 0, format, args); + va_end(args); + ret = malloc(len + 1); + va_start(args, format); + vsnprintf(ret, len+1, format, args); + va_end(args); + return ret; +} +