Commits

Anonymous committed 191c014

Submit cf-0.1 release.

Comments (0)

Files changed (1)

cf/cf_nameinfo_p.c

 /*---------------------------------------------------------------------------*
   C MODULE  cf_nameinfo_p.c
 
-  Copyright (c) 2003, James H. Woodyatt
+  Copyright (c) 2003-2004, James H. Woodyatt
   All rights reserved.
 
   Redistribution and use in source and binary forms, with or without
 static int cf_nameinfo_sockaddr_compare(value v1, value v2)
 {
     CAMLparam2(v1, v2);
-    const struct sockaddr* addr1Ptr;
-    const struct sockaddr* addr2Ptr;
+    const Cf_socket_sockaddrx_unit_t* sxPtr[2];
+    const struct sockaddr* saPtr[2];
     int result;
     
-    addr1Ptr = Cf_nameinfo_sockaddr_val(v1);
-    addr2Ptr = Cf_nameinfo_sockaddr_val(v2);
-    
-    result = addr1Ptr->sa_family - addr2Ptr->sa_family;
+    sxPtr[0] = Cf_socket_sockaddrx_unit_val(v1);
+    saPtr[0] = &sxPtr[0]->sx_sockaddr;
+    sxPtr[1] = Cf_socket_sockaddrx_unit_val(v2);    
+    saPtr[1] = &sxPtr[1]->sx_sockaddr;
+
+    result = saPtr[0]->sa_family - saPtr[1]->sa_family;
     if (!result) {
-        result = addr1Ptr->sa_len - addr2Ptr->sa_len;
-        if (!result)
-            result = memcmp(addr1Ptr, addr2Ptr,  addr1Ptr->sa_len);
+        result = sxPtr[0]->sx_socklen - sxPtr[1]->sx_socklen;
+        if (!result) {
+            size_t ssLen = sxPtr[0]->sx_socklen;
+            result = memcmp(saPtr[0]->sa_data, saPtr[1]->sa_data, ssLen);
+        }
     }
     
     CAMLreturn(result);
 }
 
-static long cf_nameinfo_sockaddr_hash(value v)
+static long cf_nameinfo_sockaddr_hash(value sxVal)
 {
-    CAMLparam1(v);
-    long result;
+    CAMLparam1(sxVal);
+    const Cf_socket_sockaddrx_unit_t* sxPtr;
+    const struct sockaddr* saPtr;
+    unsigned long result;
+    unsigned int i;
     
-    result = (long) Cf_nameinfo_sockaddr_val(v)->sa_data;    
-    CAMLreturn(result);
+    sxPtr = Cf_socket_sockaddrx_unit_val(sxVal);
+    saPtr = (const struct sockaddr*) &sxPtr->sx_sockaddr;
+    for (result = 0, i = 0; i < sxPtr->sx_socklen; ++i) {
+        unsigned long x = result >> 24;
+        result <<= 8;
+        result |= saPtr->sa_data[i] ^ x;
+    }
+    
+    CAMLreturn((long) result);
 }
 
 static void cf_nameinfo_sockaddr_serialize
-   (value v, unsigned long* size32Ptr, unsigned long* size64Ptr)
+   (value sxVal, unsigned long* size32Ptr, unsigned long* size64Ptr)
 {
-    CAMLparam1(v);
+    CAMLparam1(sxVal);
+    Cf_socket_sockaddrx_unit_t* sxPtr;
+    size_t saLen, sxLen;
+        
+    sxPtr = Cf_socket_sockaddrx_unit_val(sxVal); 
+    sxLen =
+        offsetof(Cf_socket_sockaddrx_unit_t, sx_sockaddr) +
+        sxPtr->sx_socklen;
     
-    serialize_block_1(Cf_nameinfo_sockaddr_val(v), SOCK_MAXADDRLEN);
+    serialize_int_1(sxPtr->sx_socklen);
+    serialize_block_1((void*) &sxPtr->sx_sockaddr, sxPtr->sx_socklen);
     
-    *size32Ptr = SOCK_MAXADDRLEN;
-    *size64Ptr = SOCK_MAXADDRLEN;
+    *size32Ptr = sxLen;
+    *size64Ptr = sxLen;
     
     CAMLreturn0;
 }
 
 static unsigned long cf_nameinfo_sockaddr_deserialize(void* bufferPtr)
 {
-    deserialize_block_1(bufferPtr, SOCK_MAXADDRLEN);
-    return SOCK_MAXADDRLEN;
+    Cf_socket_sockaddrx_unit_t* sxPtr;
+    size_t sxLen;
+    
+    sxPtr = (Cf_socket_sockaddrx_unit_t*) bufferPtr;
+    sxPtr->sx_socklen = deserialize_uint_1();
+    deserialize_block_1((void*) &sxPtr->sx_sockaddr, sxPtr->sx_socklen);
+
+    return
+        offsetof(Cf_socket_sockaddrx_unit_t, sx_sockaddr) +
+        sxPtr->sx_socklen;
 }
 
 static struct custom_operations cf_nameinfo_sockaddr_op = {
     cf_nameinfo_sockaddr_deserialize
 };
 
-value cf_nameinfo_sockaddr_alloc(const struct sockaddr_storage* addrPtr)
+value cf_nameinfo_sockaddr_cons(const struct sockaddr* saPtr, size_t saLen)
 {
-    value result;
+    value sxVal;
+    Cf_socket_sockaddrx_unit_t* sxPtr;
+    const size_t sxLen =
+        offsetof(Cf_socket_sockaddrx_unit_t, sx_sockaddr) + saLen;
+        
+    sxVal = alloc_custom(&cf_nameinfo_sockaddr_op, sxLen, 0, 1);
+    sxPtr = Cf_socket_sockaddrx_unit_val(sxVal);
+    if (sxPtr) {
+        sxPtr->sx_socklen = saLen;
+        memcpy(&sxPtr->sx_sockaddr, saPtr, saLen);
+    }
     
-    result = alloc_custom
-        (&cf_nameinfo_sockaddr_op, SOCK_MAXADDRLEN, 0, 1);
-    memcpy(Cf_nameinfo_sockaddr_val(result), addrPtr, SOCK_MAXADDRLEN);
-    return result;
-}
-
-value cf_nameinfo_sockaddr_cons(size_t len)
-{
-    value result;
-    
-    result = alloc_custom
-        (&cf_nameinfo_sockaddr_op, SOCK_MAXADDRLEN, 0, 1);
-    memset(Cf_nameinfo_sockaddr_val(result), 0, SOCK_MAXADDRLEN);
-    return result;
+    return sxVal;
 }
 
 static Cf_socket_domain_t cf_nameinfo_pf_unspec = {
-    PF_UNSPEC, AF_UNSPEC, cf_nameinfo_sockaddr_cons, SOCK_MAXADDRLEN
+    PF_UNSPEC, AF_UNSPEC, cf_nameinfo_sockaddr_cons,
+    sizeof(struct sockaddr_storage)
 };
 
 static value* cf_nameinfo_unresolved_exn = 0;
         unit Cf_socket.sockaddr_t -> 'af Cf_socket.domain_t ->
         'af Cf_socket.sockaddr_t option = "cf_nameinfo_specialize_sockaddr"
   ---*/
-CAMLprim value cf_nameinfo_specialize_sockaddr(value saVal, value domainVal)
+CAMLprim value cf_nameinfo_specialize_sockaddr(value sxVal, value domainVal)
 {
-    CAMLparam2(saVal, domainVal);
+    CAMLparam2(sxVal, domainVal);
     CAMLlocal1(resultVal);
     
-    const struct sockaddr* saPtr;
+    const Cf_socket_sockaddrx_unit_t* sxPtr;
     const Cf_socket_domain_t* domainPtr;
     
-    saPtr = Cf_nameinfo_sockaddr_val(saVal);
+    sxPtr = Cf_socket_sockaddrx_unit_val(sxVal);
     domainPtr = Cf_socket_domain_val(domainVal);
     resultVal = Val_int(0);
     
-    if ((int) domainPtr->d_family == (int) saPtr->sa_family) {
+    if ((int) domainPtr->d_family == (int) sxPtr->sx_sockaddr.sa_family) {
         CAMLlocal1(someVal);
-        size_t saLen;
-        saLen = domainPtr->d_socklen;
         
-        someVal = domainPtr->d_consaddr(saLen);
-        memcpy(Data_custom_val(someVal), saPtr, saLen);
+        someVal = domainPtr->d_consaddr((struct sockaddr*) &sxPtr->sx_sockaddr,
+            domainPtr->d_socklen);
 
         resultVal = alloc_small(1, 0);
         Field(resultVal, 0) = someVal;
 static const int cf_nameinfo_unresolved_array[] = {
     EAI_ADDRFAMILY, EAI_AGAIN, EAI_BADFLAGS, EAI_FAIL, EAI_FAMILY,
     EAI_MEMORY, EAI_NODATA, EAI_NONAME, EAI_SERVICE, EAI_SOCKTYPE,
-    EAI_BADHINTS, EAI_PROTOCOL
+#ifdef EAI_BADHINTS
+    EAI_BADHINTS,
+#endif
+#ifdef EAI_PROTOCOL
+    EAI_PROTOCOL
+#endif
 };
 
 #define CF_NAMEINFO_UNRESOLVED_ARRAY_SIZE \
         ni_namereqd: bool;
         ni_numericserv: bool;
         ni_dgram: bool;
-        ni_withscopeid: bool;
     }
   ---*/
 static const int cf_nameinfo_of_address_flags_array[] = {
     NI_NOFQDN, NI_NUMERICHOST, NI_NAMEREQD, NI_NUMERICSERV, NI_DGRAM,
-    NI_WITHSCOPEID
 };
 
 #define Cf_nameinfo_of_address_flags_array_size \
         'a Cf_socket.sockaddr_t -> string * string = "cf_nameinfo_of_address"
   ---*/
 CAMLprim value cf_nameinfo_of_address
-   (value hostLenVal, value servLenVal, value flagsVal, value saVal)
+   (value hostLenVal, value servLenVal, value flagsVal, value sxVal)
 {
-    CAMLparam4(hostLenVal, servLenVal, flagsVal, saVal);
+    CAMLparam4(hostLenVal, servLenVal, flagsVal, sxVal);
     CAMLlocal3(hostNameVal, servNameVal, resultVal);
     
     int error, syserror, flags;
-    const struct sockaddr* saPtr;
-    size_t saLen, hostLen, servLen;
+    const Cf_socket_sockaddrx_unit_t* sxPtr;
+    size_t ssLen, hostLen, servLen;
     char* hostName;
     char* servName;
         
         unix_error(ENOMEM, "getnameinfo", Nothing);
     }
 
-    saPtr = (const struct sockaddr*) Data_custom_val(saVal);
-    saLen = saPtr->sa_len;
+    sxPtr = Cf_socket_sockaddrx_unit_val(sxVal);
+    ssLen = sxPtr->sx_socklen;
 
     flags = 0;
     if (Is_block(flagsVal))
         flags = cf_nameinfo_of_address_flags_to_int(Field(flagsVal, 0));
     
     enter_blocking_section();
-    error = getnameinfo
-        (saPtr, saLen, hostName, hostLen, servName, servLen, flags);
+    error = getnameinfo((const struct sockaddr*) &sxPtr->sx_sockaddr, ssLen,
+        hostName, hostLen, servName, servLen, flags);
     syserror = errno;
     leave_blocking_section();
         
                 Field(cnameVal, 0) = strVal;
             }
             
-            addrVal = cf_nameinfo_sockaddr_cons(SOCK_MAXADDRLEN);
-            memcpy(Data_custom_val(addrVal), p->ai_addr, p->ai_addrlen);
+            addrVal = cf_nameinfo_sockaddr_cons(p->ai_addr, p->ai_addrlen);
             
             infoVal = alloc_small(6, 0);
             Field(infoVal, 0) = flagsVal;
   ---*/
 CAMLprim value cf_nameinfo_init(value unit)
 {
+    struct sockaddr_storage ss;
+    struct sockaddr* saPtr;
     register_custom_operations(&cf_nameinfo_sockaddr_op);
-    
+
     register_global_root(&cf_nameinfo_domain_val);
     cf_nameinfo_domain_val =
         cf_socket_domain_alloc(&cf_nameinfo_pf_unspec);
     
     register_global_root(&cf_nameinfo_unspecified_val);
+    saPtr = (struct sockaddr*) &ss;
+    memset(&ss, 0, sizeof ss);
     cf_nameinfo_unspecified_val =
-        cf_nameinfo_pf_unspec.d_consaddr(cf_nameinfo_pf_unspec.d_socklen);
+        cf_nameinfo_pf_unspec.d_consaddr(saPtr, sizeof ss);
 
     register_global_root(&cf_nameinfo_default_ai_flags_val);
     cf_nameinfo_default_ai_flags_val = alloc_small(3, 0);