emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: :family extension for make_network_process


From: Kim F. Storm
Subject: Re: :family extension for make_network_process
Date: Fri, 16 Dec 2005 01:03:42 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

Kazu Yamamoto (山本和彦) <address@hidden> writes:

> Hello,
>
> From: address@hidden (Kim F. Storm)
> Subject: Re: :family extension for make_network_process
>
>> > I would report one documentation mistake and propose an extension for
>> > make_network_process.
>> 
>> Does the following patch give good results?
>
> Yes. This code is much better than mine.
> Thanks!

It seems odd to only partially support IPv6, so here is a more
complete patch which adds an external representation of IPv6 addresses
(a 9 element vector -- 8 x 16-bit values for the address + 1 port number).

Can you pls. see if it makes sense.

BTW, with IPv4, it is custom to write 1.2.3.4:999 to separate the IP
address and port number.  Is there a similar notation for IPv6? 

I have used 1:2:3:4:5:6:7:8;999 in this patch for format-network-address
in lack of anything better....


*** process.c   01 Oct 2005 21:33:29 +0200      1.467
--- process.c   14 Dec 2005 16:42:54 +0100      
***************
*** 140,146 ****
  Lisp_Object Qprocessp;
  Lisp_Object Qrun, Qstop, Qsignal;
  Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten;
! Lisp_Object Qlocal, Qdatagram;
  Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype;
  Lisp_Object QClocal, QCremote, QCcoding;
  Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
--- 140,149 ----
  Lisp_Object Qprocessp;
  Lisp_Object Qrun, Qstop, Qsignal;
  Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten;
! Lisp_Object Qlocal, Qipv4, Qdatagram;
! #ifdef AF_INET6
! Lisp_Object Qipv6;
! #endif
  Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype;
  Lisp_Object QClocal, QCremote, QCcoding;
  Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
***************
*** 1197,1203 ****
         doc: /* Convert network ADDRESS from internal format to a string.
  If optional second argument OMIT-PORT is non-nil, don't include a port
  number in the string; in this case, interpret a 4 element vector as an
! IP address.  Returns nil if format of ADDRESS is invalid.  */)
       (address, omit_port)
       Lisp_Object address, omit_port;
  {
--- 1200,1207 ----
         doc: /* Convert network ADDRESS from internal format to a string.
  If optional second argument OMIT-PORT is non-nil, don't include a port
  number in the string; in this case, interpret a 4 element vector as an
! IPv4 address and an 8 element vector as an IPv6 address.
! Returns nil if format of ADDRESS is invalid.  */)
       (address, omit_port)
       Lisp_Object address, omit_port;
  {
***************
*** 1207,1213 ****
    if (STRINGP (address))  /* AF_LOCAL */
      return address;
  
!   if (VECTORP (address))  /* AF_INET */
      {
        register struct Lisp_Vector *p = XVECTOR (address);
        Lisp_Object args[6];
--- 1211,1217 ----
    if (STRINGP (address))  /* AF_LOCAL */
      return address;
  
!   if (VECTORP (address))  /* AF_INET or AF_INET6 */
      {
        register struct Lisp_Vector *p = XVECTOR (address);
        Lisp_Object args[6];
***************
*** 1223,1228 ****
--- 1227,1242 ----
          args[0] = build_string ("%d.%d.%d.%d:%d");
          nargs = 5;
        }
+       else if (!NILP (omit_port) && (p->size == 8 || p->size == 9))
+       {
+         args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x");
+         nargs = 8;
+       }
+       else if (p->size == 9)
+       {
+         args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x;%d");
+         nargs = 9;
+       }
        else
        return Qnil;
  
***************
*** 2212,2217 ****
--- 2226,2244 ----
        cp = (unsigned char *)&sin->sin_addr;
        break;
        }
+ #ifdef AF_INET6
+     case AF_INET6:
+       {
+       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+       len = sizeof (sin6->sin6_addr)/2 + 1;
+       address = Fmake_vector (make_number (len), Qnil);
+       p = XVECTOR (address);
+       p->contents[--len] = make_number (ntohs (sin6->sin6_port));
+       for (i = 0; i < len; i++)
+         p->contents[i] = make_number (ntohs (sin6->sin6_addr.s6_addr16[i]));
+       return address;
+       }
+ #endif
  #ifdef HAVE_LOCAL_SOCKETS
      case AF_LOCAL:
        {
***************
*** 2256,2261 ****
--- 2283,2295 ----
          *familyp = AF_INET;
          return sizeof (struct sockaddr_in);
        }
+ #ifdef AF_INET6
+       else if (p->size == 9)
+       {
+         *familyp = AF_INET6;
+         return sizeof (struct sockaddr_in6);
+       }
+ #endif
      }
  #ifdef HAVE_LOCAL_SOCKETS
    else if (STRINGP (address))
***************
*** 2302,2307 ****
--- 2336,2357 ----
          sin->sin_port = htons (i);
          cp = (unsigned char *)&sin->sin_addr;
        }
+ #ifdef AF_INET6
+       else if (family == AF_INET6)
+       {
+         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+         len = sizeof (sin6->sin6_addr) + 1;
+         i = XINT (p->contents[--len]);
+         sin6->sin6_port = htons (i);
+         for (i = 0; i < len; i++)
+           if (INTEGERP (p->contents[i]))
+             {
+               int j = XFASTINT (p->contents[i]) & 0xffff;
+               sin6->sin6_addr.s6_addr16[i] = ntohs (j);
+             }
+         return;
+       }
+ #endif
      }
    else if (STRINGP (address))
      {
***************
*** 2595,2604 ****
  stream type connection, `datagram' creates a datagram type connection.
  
  :family FAMILY -- FAMILY is the address (and protocol) family for the
! service specified by HOST and SERVICE.  The default address family is
! Inet (or IPv4) for the host and port number specified by HOST and
! SERVICE.  Other address families supported are:
    local -- for a local (i.e. UNIX) address specified by SERVICE.
  
  :local ADDRESS -- ADDRESS is the local address used for the connection.
  This parameter is ignored when opening a client process. When specified
--- 2645,2657 ----
  stream type connection, `datagram' creates a datagram type connection.
  
  :family FAMILY -- FAMILY is the address (and protocol) family for the
! service specified by HOST and SERVICE.  The default (nil) is to use
! whatever address family (IPv4 or IPv6) that is defined for the host
! and port number specified by HOST and SERVICE.  Other address families
! supported are:
    local -- for a local (i.e. UNIX) address specified by SERVICE.
+   ipv4  -- use IPv4 address family only.
+   ipv6  -- use IPv6 address family only.
  
  :local ADDRESS -- ADDRESS is the local address used for the connection.
  This parameter is ignored when opening a client process. When specified
***************
*** 2855,2873 ****
  
    /* :family FAMILY -- nil (for Inet), local, or integer.  */
    tem = Fplist_get (contact, QCfamily);
!   if (INTEGERP (tem))
!     family = XINT (tem);
!   else
      {
!       if (NILP (tem))
!       family = AF_INET;
! #ifdef HAVE_LOCAL_SOCKETS
!       else if (EQ (tem, Qlocal))
!       family = AF_LOCAL;
  #endif
      }
!   if (family < 0)
      error ("Unknown address family");
    ai.ai_family = family;
  
    /* :service SERVICE -- string, integer (port number), or t (random port).  
*/
--- 2908,2936 ----
  
    /* :family FAMILY -- nil (for Inet), local, or integer.  */
    tem = Fplist_get (contact, QCfamily);
!   if (NILP (tem))
      {
! #ifdef HAVE_GETADDRINFO
!       family = AF_UNSPEC;
! #else
!       family = AF_INET;
  #endif
      }
! #ifdef HAVE_LOCAL_SOCKETS
!   else if (EQ (tem, Qlocal))
!     family = AF_LOCAL;
! #endif
! #ifdef AF_INET6
!   else if (EQ (tem, Qipv6))
!     family = AF_INET6;
! #endif
!   else if (EQ (tem, Qipv4))
!     family = AF_INET;
!   else if (INTEGERP (tem))
!     family = XINT (tem);
!   else
      error ("Unknown address family");
+ 
    ai.ai_family = family;
  
    /* :service SERVICE -- string, integer (port number), or t (random port).  
*/
***************
*** 2933,2939 ****
        QUIT;
        memset (&hints, 0, sizeof (hints));
        hints.ai_flags = 0;
!       hints.ai_family = NILP (Fplist_member (contact, QCfamily)) ? AF_UNSPEC 
: family;
        hints.ai_socktype = socktype;
        hints.ai_protocol = 0;
        ret = getaddrinfo (SDATA (host), portstring, &hints, &res);
--- 2996,3002 ----
        QUIT;
        memset (&hints, 0, sizeof (hints));
        hints.ai_flags = 0;
!       hints.ai_family = family;
        hints.ai_socktype = socktype;
        hints.ai_protocol = 0;
        ret = getaddrinfo (SDATA (host), portstring, &hints, &res);
***************
*** 3816,3821 ****
--- 3879,3887 ----
    union u_sockaddr {
      struct sockaddr sa;
      struct sockaddr_in in;
+ #ifdef AF_INET6
+     struct sockaddr_in6 in6;
+ #endif
  #ifdef HAVE_LOCAL_SOCKETS
      struct sockaddr_un un;
  #endif
***************
*** 3872,3877 ****
--- 3938,3963 ----
        }
        break;
  
+ #ifdef AF_INET6
+     case AF_INET6:
+       {
+       Lisp_Object args[9];
+       uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr.s6_addr16;
+       int i;
+       args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x");
+       for (i = 0; i < 8; i++)
+         args[i+1] = make_number (ntohs(ip6[i]));
+       host = Fformat (9, args);
+       service = make_number (ntohs (saddr.in.sin_port));
+ 
+       args[0] = build_string (" <%s;%d>");
+       args[1] = host;
+       args[2] = service;
+       caller = Fformat (3, args);
+       }
+       break;
+ #endif
+ 
  #ifdef HAVE_LOCAL_SOCKETS
      case AF_LOCAL:
  #endif
***************
*** 6724,6729 ****
--- 6810,6819 ----
  #ifdef HAVE_LOCAL_SOCKETS
     ADD_SUBFEATURE (QCfamily, Qlocal);
  #endif
+    ADD_SUBFEATURE (QCfamily, Qipv4);
+ #ifdef AF_INET6
+    ADD_SUBFEATURE (QCfamily, Qipv6);
+ #endif
  #ifdef HAVE_GETSOCKNAME
     ADD_SUBFEATURE (QCservice, Qt);
  #endif
***************
*** 6782,6787 ****
--- 6872,6883 ----
    staticpro (&Qlisten);
    Qlocal = intern ("local");
    staticpro (&Qlocal);
+   Qipv4 = intern ("ipv4");
+   staticpro (&Qipv4);
+ #ifdef AF_INET6
+   Qipv6 = intern ("ipv6");
+   staticpro (&Qipv6);
+ #endif
    Qdatagram = intern ("datagram");
    staticpro (&Qdatagram);
  

-- 
Kim F. Storm <address@hidden> http://www.cua.dk





reply via email to

[Prev in Thread] Current Thread [Next in Thread]