X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibpsocket.so_src%2Fgetaddrinfo.c;h=e1a0e424a4266a297d44e08e594600cc262bdd5d;hb=bdab8e5cebaf249d291d19523d0358f8c1c98008;hp=bd50f9117b61396b706dbde6c9bafc7bc67a0fb0;hpb=c6eb9805c1835736a71c1415ced824744c66ff91;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c index bd50f911..e1a0e424 100644 --- a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c +++ b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c @@ -13,6 +13,16 @@ #include // strtol #include +// === TYPES === +struct sLookupInfo { + struct addrinfo **ret_p; +}; + +// === PROTOTYPES === +struct addrinfo *int_new_addrinfo(int af, const void *addrdata); +int int_getaddinfo_lookupcb(void *info, int addr_type, const void *addr); + +// === GLOBALS === static const struct { const char *Name; int SockType; @@ -52,28 +62,20 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi { // 1. Check if the node is an IP address { - int type; char addrdata[16]; - type = Net_ParseAddress(node, addrdata); + int type = Net_ParseAddress(node, addrdata); switch(type) { - case 0: + case NET_ADDRTYPE_NULL: + break; + case NET_ADDRTYPE_IPV4: + ret = int_new_addrinfo(AF_INET, addrdata); 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 ); + case NET_ADDRTYPE_IPV6: + ret = int_new_addrinfo(AF_INET6, addrdata); break; default: - _SysDebug("getaddrinfo: Unknown address family %i", type); + _SysDebug("getaddrinfo: Unknown address type %i", type); return 1; } } @@ -82,13 +84,19 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi // - No luck with above, and hints->ai_flags doesn't have AI_NUMERICHOST set if( !ret && !(hints->ai_flags & AI_NUMERICHOST) ) { - _SysDebug("getaddrinfo: TODO DNS Lookups"); - // TODO: DNS Lookups - // ? /Acess/Conf/Nameservers - // ? /Acess/Conf/Hosts + // Just does a basic A record lookup + // TODO: Support SRV records + // TODO: Ensure that CNAMEs are handled correctly + struct sLookupInfo info = { + .ret_p = &ret, + }; + if( Net_Lookup_Addrs(node, &info, int_getaddinfo_lookupcb) ) { + // Lookup failed, quick return + return EAI_NONAME; + } } - // 3. No Match, chuck sad + // 3. No Match, return sad if( !ret ) { return EAI_NONAME; @@ -142,8 +150,7 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi } } - struct addrinfo *ai; - for( ai = ret; ai; ai = ai->ai_next) + for( struct addrinfo *ai = ret; ai; ai = ai->ai_next) { struct sockaddr_in *in = (void*)ai->ai_addr; struct sockaddr_in6 *in6 = (void*)ai->ai_addr; @@ -181,9 +188,81 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi return 0; } +/** + * \brief Allocate a new zeroed addrinfo for the specified address + */ +struct addrinfo *int_new_addrinfo(int af, const void *addrdata) +{ + size_t addrlen = 0; + switch(af) + { + case AF_INET: + addrlen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + addrlen = sizeof(struct sockaddr_in6); + break; + default: + _SysDebug("int_new_addrinfo: ERROR - Unknown AF %i", af); + return NULL; + } + struct addrinfo* ret = malloc(sizeof(struct addrinfo) + addrlen); + ret->ai_family = af; + ret->ai_socktype = 0; + ret->ai_protocol = 0; + ret->ai_addrlen = addrlen; + ret->ai_addr = (void*)( ret + 1 ); + ret->ai_canonname = 0; + ret->ai_next = 0; + switch(af) + { + case AF_INET: + ((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; + case AF_INET6: + ((struct sockaddr_in6*)ret->ai_addr)->sin6_family = AF_INET6; + ((struct sockaddr_in6*)ret->ai_addr)->sin6_port = 0; + memcpy( &((struct sockaddr_in6*)ret->ai_addr)->sin6_addr, addrdata, 16 ); + break; + default: + _SysDebug("int_new_addrinfo: BUGCHECK - Unhandled AF %i", af); + return NULL; + } + return ret; +} + +// Callback for getaddrinfo's call to Net_Lookup_Addrs +int int_getaddinfo_lookupcb(void *info_v, int addr_type, const void *addr) +{ + struct sLookupInfo *info = info_v; + struct addrinfo *ent; + switch( addr_type ) + { + case NET_ADDRTYPE_IPV4: + ent = int_new_addrinfo(AF_INET, addr); + break; + case NET_ADDRTYPE_IPV6: + ent = int_new_addrinfo(AF_INET6, addr); + break; + default: + // Huh... unknown address type, just ignore it + return 0; + } + ent->ai_next = *info->ret_p; + *info->ret_p = ent; + return 0; +} + void freeaddrinfo(struct addrinfo *res) { - + while( res ) + { + struct addrinfo *next = res->ai_next; + free(res); + res = next; + } } int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) @@ -235,3 +314,8 @@ const char *gai_strerror(int errnum) } } +struct hostent *gethostbyname(const char *name) +{ + return NULL; +} +