aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorKim F. Storm2006-01-04 00:16:54 +0000
committerKim F. Storm2006-01-04 00:16:54 +0000
commite1652a86127e201a0e867a62545ec53de7376f3b (patch)
tree14908a76b3ad2d3f491382ae9f330091942b9c24 /src/process.c
parentdd878ee14851f3d201266f451f5801195932d57f (diff)
downloademacs-e1652a86127e201a0e867a62545ec53de7376f3b.tar.gz
emacs-e1652a86127e201a0e867a62545ec53de7376f3b.zip
Add IPv6 support.
(Qipv4, Qipv6): New vars. (syms_of_process): Intern and staticpro them. (Fformat_network_address): Handle 9 or 8 element vector as IPv6 address with or without port number. Handle 4 element vector as IPv4 address without port number. (conv_sockaddr_to_lisp, get_lisp_to_sockaddr_size) (conv_lisp_to_sockaddr): Handle IPv6 addresses. (Fmake_network_process): Use :family 'ipv4 and 'ipv6 to explicitly request that address family only. :family nil or omitted means to determine address family from the specified :host and :service. (server_accept_connection): Handle IPv6 addresses. (init_process): Add (:family ipv4) and (:family ipv6) sub-features. (ifflag_table): Add missing OpenBSD IFF_ flags.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c154
1 files changed, 134 insertions, 20 deletions
diff --git a/src/process.c b/src/process.c
index b88617a2c0f..c842b798c43 100644
--- a/src/process.c
+++ b/src/process.c
@@ -140,7 +140,10 @@ Boston, MA 02110-1301, USA. */
140Lisp_Object Qprocessp; 140Lisp_Object Qprocessp;
141Lisp_Object Qrun, Qstop, Qsignal; 141Lisp_Object Qrun, Qstop, Qsignal;
142Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; 142Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten;
143Lisp_Object Qlocal, Qdatagram; 143Lisp_Object Qlocal, Qipv4, Qdatagram;
144#ifdef AF_INET6
145Lisp_Object Qipv6;
146#endif
144Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; 147Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype;
145Lisp_Object QClocal, QCremote, QCcoding; 148Lisp_Object QClocal, QCremote, QCcoding;
146Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; 149Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
@@ -1195,9 +1198,11 @@ a socket connection. */)
1195DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address, 1198DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address,
1196 1, 2, 0, 1199 1, 2, 0,
1197 doc: /* Convert network ADDRESS from internal format to a string. 1200 doc: /* Convert network ADDRESS from internal format to a string.
1201A 4 or 5 element vector represents an IPv4 address (with port number).
1202An 8 or 9 element vector represents an IPv6 address (with port number).
1198If optional second argument OMIT-PORT is non-nil, don't include a port 1203If optional second argument OMIT-PORT is non-nil, don't include a port
1199number in the string; in this case, interpret a 4 element vector as an 1204number in the string, even when present in ADDRESS.
1200IP address. Returns nil if format of ADDRESS is invalid. */) 1205Returns nil if format of ADDRESS is invalid. */)
1201 (address, omit_port) 1206 (address, omit_port)
1202 Lisp_Object address, omit_port; 1207 Lisp_Object address, omit_port;
1203{ 1208{
@@ -1207,13 +1212,13 @@ IP address. Returns nil if format of ADDRESS is invalid. */)
1207 if (STRINGP (address)) /* AF_LOCAL */ 1212 if (STRINGP (address)) /* AF_LOCAL */
1208 return address; 1213 return address;
1209 1214
1210 if (VECTORP (address)) /* AF_INET */ 1215 if (VECTORP (address)) /* AF_INET or AF_INET6 */
1211 { 1216 {
1212 register struct Lisp_Vector *p = XVECTOR (address); 1217 register struct Lisp_Vector *p = XVECTOR (address);
1213 Lisp_Object args[6]; 1218 Lisp_Object args[6];
1214 int nargs, i; 1219 int nargs, i;
1215 1220
1216 if (!NILP (omit_port) && (p->size == 4 || p->size == 5)) 1221 if (p->size == 4 || (p->size == 5 && !NILP (omit_port)))
1217 { 1222 {
1218 args[0] = build_string ("%d.%d.%d.%d"); 1223 args[0] = build_string ("%d.%d.%d.%d");
1219 nargs = 4; 1224 nargs = 4;
@@ -1223,6 +1228,16 @@ IP address. Returns nil if format of ADDRESS is invalid. */)
1223 args[0] = build_string ("%d.%d.%d.%d:%d"); 1228 args[0] = build_string ("%d.%d.%d.%d:%d");
1224 nargs = 5; 1229 nargs = 5;
1225 } 1230 }
1231 else if (p->size == 8 || (p->size == 9 && !NILP (omit_port)))
1232 {
1233 args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x");
1234 nargs = 8;
1235 }
1236 else if (p->size == 9)
1237 {
1238 args[0] = build_string ("[%x:%x:%x:%x:%x:%x:%x:%x]:%d");
1239 nargs = 9;
1240 }
1226 else 1241 else
1227 return Qnil; 1242 return Qnil;
1228 1243
@@ -2212,6 +2227,20 @@ conv_sockaddr_to_lisp (sa, len)
2212 cp = (unsigned char *)&sin->sin_addr; 2227 cp = (unsigned char *)&sin->sin_addr;
2213 break; 2228 break;
2214 } 2229 }
2230#ifdef AF_INET6
2231 case AF_INET6:
2232 {
2233 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
2234 uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr;
2235 len = sizeof (sin6->sin6_addr)/2 + 1;
2236 address = Fmake_vector (make_number (len), Qnil);
2237 p = XVECTOR (address);
2238 p->contents[--len] = make_number (ntohs (sin6->sin6_port));
2239 for (i = 0; i < len; i++)
2240 p->contents[i] = make_number (ntohs (ip6[i]));
2241 return address;
2242 }
2243#endif
2215#ifdef HAVE_LOCAL_SOCKETS 2244#ifdef HAVE_LOCAL_SOCKETS
2216 case AF_LOCAL: 2245 case AF_LOCAL:
2217 { 2246 {
@@ -2256,6 +2285,13 @@ get_lisp_to_sockaddr_size (address, familyp)
2256 *familyp = AF_INET; 2285 *familyp = AF_INET;
2257 return sizeof (struct sockaddr_in); 2286 return sizeof (struct sockaddr_in);
2258 } 2287 }
2288#ifdef AF_INET6
2289 else if (p->size == 9)
2290 {
2291 *familyp = AF_INET6;
2292 return sizeof (struct sockaddr_in6);
2293 }
2294#endif
2259 } 2295 }
2260#ifdef HAVE_LOCAL_SOCKETS 2296#ifdef HAVE_LOCAL_SOCKETS
2261 else if (STRINGP (address)) 2297 else if (STRINGP (address))
@@ -2302,6 +2338,23 @@ conv_lisp_to_sockaddr (family, address, sa, len)
2302 sin->sin_port = htons (i); 2338 sin->sin_port = htons (i);
2303 cp = (unsigned char *)&sin->sin_addr; 2339 cp = (unsigned char *)&sin->sin_addr;
2304 } 2340 }
2341#ifdef AF_INET6
2342 else if (family == AF_INET6)
2343 {
2344 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
2345 uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr;
2346 len = sizeof (sin6->sin6_addr) + 1;
2347 i = XINT (p->contents[--len]);
2348 sin6->sin6_port = htons (i);
2349 for (i = 0; i < len; i++)
2350 if (INTEGERP (p->contents[i]))
2351 {
2352 int j = XFASTINT (p->contents[i]) & 0xffff;
2353 ip6[i] = ntohs (j);
2354 }
2355 return;
2356 }
2357#endif
2305 } 2358 }
2306 else if (STRINGP (address)) 2359 else if (STRINGP (address))
2307 { 2360 {
@@ -2595,10 +2648,13 @@ a random port number is selected for the server.
2595stream type connection, `datagram' creates a datagram type connection. 2648stream type connection, `datagram' creates a datagram type connection.
2596 2649
2597:family FAMILY -- FAMILY is the address (and protocol) family for the 2650:family FAMILY -- FAMILY is the address (and protocol) family for the
2598service specified by HOST and SERVICE. The default address family is 2651service specified by HOST and SERVICE. The default (nil) is to use
2599Inet (or IPv4) for the host and port number specified by HOST and 2652whatever address family (IPv4 or IPv6) that is defined for the host
2600SERVICE. Other address families supported are: 2653and port number specified by HOST and SERVICE. Other address families
2654supported are:
2601 local -- for a local (i.e. UNIX) address specified by SERVICE. 2655 local -- for a local (i.e. UNIX) address specified by SERVICE.
2656 ipv4 -- use IPv4 address family only.
2657 ipv6 -- use IPv6 address family only.
2602 2658
2603:local ADDRESS -- ADDRESS is the local address used for the connection. 2659:local ADDRESS -- ADDRESS is the local address used for the connection.
2604This parameter is ignored when opening a client process. When specified 2660This parameter is ignored when opening a client process. When specified
@@ -2715,8 +2771,8 @@ usage: (make-network-process &rest ARGS) */)
2715 struct Lisp_Process *p; 2771 struct Lisp_Process *p;
2716#ifdef HAVE_GETADDRINFO 2772#ifdef HAVE_GETADDRINFO
2717 struct addrinfo ai, *res, *lres; 2773 struct addrinfo ai, *res, *lres;
2718 struct addrinfo hints; 2774 struct addrinfo hints;
2719 char *portstring, portbuf[128]; 2775 char *portstring, portbuf[128];
2720#else /* HAVE_GETADDRINFO */ 2776#else /* HAVE_GETADDRINFO */
2721 struct _emacs_addrinfo 2777 struct _emacs_addrinfo
2722 { 2778 {
@@ -2855,19 +2911,29 @@ usage: (make-network-process &rest ARGS) */)
2855 2911
2856 /* :family FAMILY -- nil (for Inet), local, or integer. */ 2912 /* :family FAMILY -- nil (for Inet), local, or integer. */
2857 tem = Fplist_get (contact, QCfamily); 2913 tem = Fplist_get (contact, QCfamily);
2858 if (INTEGERP (tem)) 2914 if (NILP (tem))
2859 family = XINT (tem);
2860 else
2861 { 2915 {
2862 if (NILP (tem)) 2916#ifdef HAVE_GETADDRINFO
2863 family = AF_INET; 2917 family = AF_UNSPEC;
2864#ifdef HAVE_LOCAL_SOCKETS 2918#else
2865 else if (EQ (tem, Qlocal)) 2919 family = AF_INET;
2866 family = AF_LOCAL;
2867#endif 2920#endif
2868 } 2921 }
2869 if (family < 0) 2922#ifdef HAVE_LOCAL_SOCKETS
2923 else if (EQ (tem, Qlocal))
2924 family = AF_LOCAL;
2925#endif
2926#ifdef AF_INET6
2927 else if (EQ (tem, Qipv6))
2928 family = AF_INET6;
2929#endif
2930 else if (EQ (tem, Qipv4))
2931 family = AF_INET;
2932 else if (INTEGERP (tem))
2933 family = XINT (tem);
2934 else
2870 error ("Unknown address family"); 2935 error ("Unknown address family");
2936
2871 ai.ai_family = family; 2937 ai.ai_family = family;
2872 2938
2873 /* :service SERVICE -- string, integer (port number), or t (random port). */ 2939 /* :service SERVICE -- string, integer (port number), or t (random port). */
@@ -2933,7 +2999,7 @@ usage: (make-network-process &rest ARGS) */)
2933 QUIT; 2999 QUIT;
2934 memset (&hints, 0, sizeof (hints)); 3000 memset (&hints, 0, sizeof (hints));
2935 hints.ai_flags = 0; 3001 hints.ai_flags = 0;
2936 hints.ai_family = NILP (Fplist_member (contact, QCfamily)) ? AF_UNSPEC : family; 3002 hints.ai_family = family;
2937 hints.ai_socktype = socktype; 3003 hints.ai_socktype = socktype;
2938 hints.ai_protocol = 0; 3004 hints.ai_protocol = 0;
2939 ret = getaddrinfo (SDATA (host), portstring, &hints, &res); 3005 ret = getaddrinfo (SDATA (host), portstring, &hints, &res);
@@ -3522,6 +3588,21 @@ static struct ifflag_def ifflag_table[] = {
3522#ifdef IFF_DYNAMIC 3588#ifdef IFF_DYNAMIC
3523 { IFF_DYNAMIC, "dynamic" }, 3589 { IFF_DYNAMIC, "dynamic" },
3524#endif 3590#endif
3591#ifdef IFF_OACTIV
3592 { IFF_OACTIV, "oactiv" }, /* OpenBSD: transmission in progress */
3593#endif
3594#ifdef IFF_SIMPLEX
3595 { IFF_SIMPLEX, "simplex" }, /* OpenBSD: can't hear own transmissions */
3596#endif
3597#ifdef IFF_LINK0
3598 { IFF_LINK0, "link0" }, /* OpenBSD: per link layer defined bit */
3599#endif
3600#ifdef IFF_LINK1
3601 { IFF_LINK1, "link1" }, /* OpenBSD: per link layer defined bit */
3602#endif
3603#ifdef IFF_LINK2
3604 { IFF_LINK2, "link2" }, /* OpenBSD: per link layer defined bit */
3605#endif
3525 { 0, 0 } 3606 { 0, 0 }
3526}; 3607};
3527 3608
@@ -3816,6 +3897,9 @@ server_accept_connection (server, channel)
3816 union u_sockaddr { 3897 union u_sockaddr {
3817 struct sockaddr sa; 3898 struct sockaddr sa;
3818 struct sockaddr_in in; 3899 struct sockaddr_in in;
3900#ifdef AF_INET6
3901 struct sockaddr_in6 in6;
3902#endif
3819#ifdef HAVE_LOCAL_SOCKETS 3903#ifdef HAVE_LOCAL_SOCKETS
3820 struct sockaddr_un un; 3904 struct sockaddr_un un;
3821#endif 3905#endif
@@ -3872,6 +3956,26 @@ server_accept_connection (server, channel)
3872 } 3956 }
3873 break; 3957 break;
3874 3958
3959#ifdef AF_INET6
3960 case AF_INET6:
3961 {
3962 Lisp_Object args[9];
3963 uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr;
3964 int i;
3965 args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x");
3966 for (i = 0; i < 8; i++)
3967 args[i+1] = make_number (ntohs(ip6[i]));
3968 host = Fformat (9, args);
3969 service = make_number (ntohs (saddr.in.sin_port));
3970
3971 args[0] = build_string (" <[%s]:%d>");
3972 args[1] = host;
3973 args[2] = service;
3974 caller = Fformat (3, args);
3975 }
3976 break;
3977#endif
3978
3875#ifdef HAVE_LOCAL_SOCKETS 3979#ifdef HAVE_LOCAL_SOCKETS
3876 case AF_LOCAL: 3980 case AF_LOCAL:
3877#endif 3981#endif
@@ -6724,6 +6828,10 @@ init_process ()
6724#ifdef HAVE_LOCAL_SOCKETS 6828#ifdef HAVE_LOCAL_SOCKETS
6725 ADD_SUBFEATURE (QCfamily, Qlocal); 6829 ADD_SUBFEATURE (QCfamily, Qlocal);
6726#endif 6830#endif
6831 ADD_SUBFEATURE (QCfamily, Qipv4);
6832#ifdef AF_INET6
6833 ADD_SUBFEATURE (QCfamily, Qipv6);
6834#endif
6727#ifdef HAVE_GETSOCKNAME 6835#ifdef HAVE_GETSOCKNAME
6728 ADD_SUBFEATURE (QCservice, Qt); 6836 ADD_SUBFEATURE (QCservice, Qt);
6729#endif 6837#endif
@@ -6782,6 +6890,12 @@ syms_of_process ()
6782 staticpro (&Qlisten); 6890 staticpro (&Qlisten);
6783 Qlocal = intern ("local"); 6891 Qlocal = intern ("local");
6784 staticpro (&Qlocal); 6892 staticpro (&Qlocal);
6893 Qipv4 = intern ("ipv4");
6894 staticpro (&Qipv4);
6895#ifdef AF_INET6
6896 Qipv6 = intern ("ipv6");
6897 staticpro (&Qipv6);
6898#endif
6785 Qdatagram = intern ("datagram"); 6899 Qdatagram = intern ("datagram");
6786 staticpro (&Qdatagram); 6900 staticpro (&Qdatagram);
6787 6901