comparison src/process.c @ 68008:10f0a09ec82e

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.
author Kim F. Storm <storm@cua.dk>
date Wed, 04 Jan 2006 00:16:54 +0000
parents 8f3c10fea90b
children e213d76ca446
comparison
equal deleted inserted replaced
68007:0b578812ab24 68008:10f0a09ec82e
138 #include "atimer.h" 138 #include "atimer.h"
139 139
140 Lisp_Object Qprocessp; 140 Lisp_Object Qprocessp;
141 Lisp_Object Qrun, Qstop, Qsignal; 141 Lisp_Object Qrun, Qstop, Qsignal;
142 Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; 142 Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten;
143 Lisp_Object Qlocal, Qdatagram; 143 Lisp_Object Qlocal, Qipv4, Qdatagram;
144 #ifdef AF_INET6
145 Lisp_Object Qipv6;
146 #endif
144 Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; 147 Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype;
145 Lisp_Object QClocal, QCremote, QCcoding; 148 Lisp_Object QClocal, QCremote, QCcoding;
146 Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; 149 Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
147 Lisp_Object QCsentinel, QClog, QCoptions, QCplist; 150 Lisp_Object QCsentinel, QClog, QCoptions, QCplist;
148 Lisp_Object QCfilter_multibyte; 151 Lisp_Object QCfilter_multibyte;
1193 1196
1194 #ifdef HAVE_SOCKETS 1197 #ifdef HAVE_SOCKETS
1195 DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address, 1198 DEFUN ("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.
1201 A 4 or 5 element vector represents an IPv4 address (with port number).
1202 An 8 or 9 element vector represents an IPv6 address (with port number).
1198 If optional second argument OMIT-PORT is non-nil, don't include a port 1203 If optional second argument OMIT-PORT is non-nil, don't include a port
1199 number in the string; in this case, interpret a 4 element vector as an 1204 number in the string, even when present in ADDRESS.
1200 IP address. Returns nil if format of ADDRESS is invalid. */) 1205 Returns 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 {
1204 if (NILP (address)) 1209 if (NILP (address))
1205 return Qnil; 1210 return Qnil;
1206 1211
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;
1220 } 1225 }
1221 else if (p->size == 5) 1226 else if (p->size == 5)
1222 { 1227 {
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;
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;
1225 } 1240 }
1226 else 1241 else
1227 return Qnil; 1242 return Qnil;
1228 1243
1229 for (i = 0; i < nargs; i++) 1244 for (i = 0; i < nargs; i++)
2210 p = XVECTOR (address); 2225 p = XVECTOR (address);
2211 p->contents[--len] = make_number (ntohs (sin->sin_port)); 2226 p->contents[--len] = make_number (ntohs (sin->sin_port));
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 {
2218 struct sockaddr_un *sockun = (struct sockaddr_un *) sa; 2247 struct sockaddr_un *sockun = (struct sockaddr_un *) sa;
2219 for (i = 0; i < sizeof (sockun->sun_path); i++) 2248 for (i = 0; i < sizeof (sockun->sun_path); i++)
2254 if (p->size == 5) 2283 if (p->size == 5)
2255 { 2284 {
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))
2262 { 2298 {
2263 *familyp = AF_LOCAL; 2299 *familyp = AF_LOCAL;
2300 len = sizeof (sin->sin_addr) + 1; 2336 len = sizeof (sin->sin_addr) + 1;
2301 i = XINT (p->contents[--len]); 2337 i = XINT (p->contents[--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 {
2308 #ifdef HAVE_LOCAL_SOCKETS 2361 #ifdef HAVE_LOCAL_SOCKETS
2309 if (family == AF_LOCAL) 2362 if (family == AF_LOCAL)
2593 2646
2594 :type TYPE -- TYPE is the type of connection. The default (nil) is a 2647 :type TYPE -- TYPE is the type of connection. The default (nil) is a
2595 stream type connection, `datagram' creates a datagram type connection. 2648 stream 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
2598 service specified by HOST and SERVICE. The default address family is 2651 service specified by HOST and SERVICE. The default (nil) is to use
2599 Inet (or IPv4) for the host and port number specified by HOST and 2652 whatever address family (IPv4 or IPv6) that is defined for the host
2600 SERVICE. Other address families supported are: 2653 and port number specified by HOST and SERVICE. Other address families
2654 supported 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.
2604 This parameter is ignored when opening a client process. When specified 2660 This parameter is ignored when opening a client process. When specified
2605 for a server process, the FAMILY, HOST and SERVICE args are ignored. 2661 for a server process, the FAMILY, HOST and SERVICE args are ignored.
2606 2662
2713 Lisp_Object proc; 2769 Lisp_Object proc;
2714 Lisp_Object contact; 2770 Lisp_Object contact;
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 {
2723 int ai_family; 2779 int ai_family;
2724 int ai_socktype; 2780 int ai_socktype;
2853 goto open_socket; 2909 goto open_socket;
2854 } 2910 }
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))
2915 {
2916 #ifdef HAVE_GETADDRINFO
2917 family = AF_UNSPEC;
2918 #else
2919 family = AF_INET;
2920 #endif
2921 }
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))
2859 family = XINT (tem); 2933 family = XINT (tem);
2860 else 2934 else
2861 {
2862 if (NILP (tem))
2863 family = AF_INET;
2864 #ifdef HAVE_LOCAL_SOCKETS
2865 else if (EQ (tem, Qlocal))
2866 family = AF_LOCAL;
2867 #endif
2868 }
2869 if (family < 0)
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). */
2874 service = Fplist_get (contact, QCservice); 2940 service = Fplist_get (contact, QCservice);
2875 2941
2931 2997
2932 immediate_quit = 1; 2998 immediate_quit = 1;
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);
2940 if (ret) 3006 if (ret)
2941 #ifdef HAVE_GAI_STRERROR 3007 #ifdef HAVE_GAI_STRERROR
3520 { IFF_AUTOMEDIA, "automedia" }, 3586 { IFF_AUTOMEDIA, "automedia" },
3521 #endif 3587 #endif
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
3528 DEFUN ("network-interface-info", Fnetwork_interface_info, Snetwork_interface_info, 1, 1, 0, 3609 DEFUN ("network-interface-info", Fnetwork_interface_info, Snetwork_interface_info, 1, 1, 0,
3529 doc: /* Return information about network interface named IFNAME. 3610 doc: /* Return information about network interface named IFNAME.
3814 struct Lisp_Process *p; 3895 struct Lisp_Process *p;
3815 int s; 3896 int s;
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
3822 } saddr; 3906 } saddr;
3823 int len = sizeof saddr; 3907 int len = sizeof saddr;
3869 args[1] = host; 3953 args[1] = host;
3870 args[2] = service; 3954 args[2] = service;
3871 caller = Fformat (3, args); 3955 caller = Fformat (3, args);
3872 } 3956 }
3873 break; 3957 break;
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
3874 3978
3875 #ifdef HAVE_LOCAL_SOCKETS 3979 #ifdef HAVE_LOCAL_SOCKETS
3876 case AF_LOCAL: 3980 case AF_LOCAL:
3877 #endif 3981 #endif
3878 default: 3982 default:
6722 ADD_SUBFEATURE (QCtype, Qdatagram); 6826 ADD_SUBFEATURE (QCtype, Qdatagram);
6723 #endif 6827 #endif
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
6730 #if !defined(TERM) && (defined(O_NONBLOCK) || defined(O_NDELAY)) 6838 #if !defined(TERM) && (defined(O_NONBLOCK) || defined(O_NDELAY))
6731 ADD_SUBFEATURE (QCserver, Qt); 6839 ADD_SUBFEATURE (QCserver, Qt);
6780 staticpro (&Qfailed); 6888 staticpro (&Qfailed);
6781 Qlisten = intern ("listen"); 6889 Qlisten = intern ("listen");
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
6788 QCname = intern (":name"); 6902 QCname = intern (":name");
6789 staticpro (&QCname); 6903 staticpro (&QCname);