Usermode/libpsocket - Heaps of work on getaddrinfo
authorJohn Hodge <[email protected]>
Sun, 27 May 2012 10:27:00 +0000 (18:27 +0800)
committerJohn Hodge <[email protected]>
Sun, 27 May 2012 10:27:00 +0000 (18:27 +0800)
Usermode/Libraries/libpsocket.so_src/Makefile
Usermode/Libraries/libpsocket.so_src/getaddrinfo.c
Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h
Usermode/Libraries/libpsocket.so_src/main.c

index ee0b579..81418ad 100644 (file)
@@ -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
index e122a5a..57120f0 100644 (file)
  */
 #include <netdb.h>
 #include <netinet/in.h>
+#include <net.h>       // Net_ParseAddress
+#include <stdlib.h>    // malloc
+#include <string.h>    // memcpy
+#include <acess/sys.h>
 
 // === 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";
        }
 }
index cea819c..e9cf788 100644 (file)
@@ -1,7 +1,29 @@
 #ifndef _LIBPSOCKET__NETDB_H_
 #define _LIBPSOCKET__NETDB_H_
 
-typedef unsigned int   socklen_t;
+#include <sys/socket.h>
+
+#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
 {
index 09b3987..99fbe2a 100644 (file)
@@ -5,9 +5,28 @@
  * main.c
  * - Entrypoint and misc code
  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
 
 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;
+}
+

UCC git Repository :: git.ucc.asn.au