X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibpsocket.so_src%2Fgetaddrinfo.c;h=57120f0d0f181121c912ac9227efc484db6137c2;hb=fb3abbad5dfd71ea2b190d0b33d9c57e879fb15a;hp=e122a5aadf76e443a71e5daccc2c07ba73dca5e7;hpb=0dfc38f0ca6b391b15154e3173b5c9504df17f84;p=tpg%2Facess2.git 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"; } }