Re: nc -U -u (Unix datagram socket support)
That looks good. .Fn mktemp was marked as a legacy interface in -.St -p1003.1-2001 -and may be removed in a future release of -.Ox . +.St -p1003.1-2001 . That looks good too. I think that whoever wrote that saw smoking something. No, that is completely accurate. mktemp(3) was marked as a legacy interface and does not appear in POSIX 1003-2008, which only specifies mkdtemp() and mkstemp(). A lot of legacy interfaces were dropped in 1003-2008. If it isn't in POSIX anymore, then there is no need to mention POSIX. mktemp(3) is a fact on the ground. It can be used safely, in a loop. Furthermore, noone can remove it from their libc, since code which does use it safely exists. If we remove it from libc, those authors who need it (to create AF_UNIX sockets, device nodes, or named pipes) will rewrite it themselves, much worse. In my view, the paragraph glorifies POSIX above what it is due. Who gives a shit if something is in POSIX. Noone reads POSIX; it is not published and the only people reading it are using the pirated pdf's circling around.
Re: nc -U -u (Unix datagram socket support)
jmc@ and I discussed these man page changes. He's OK with this patch, but would like another network developer to approve. So, looking for OKs. Jeremy Index: nc.1 === RCS file: /cvs/src/usr.bin/nc/nc.1,v retrieving revision 1.56 diff -u -p -r1.56 nc.1 --- nc.18 Jan 2011 00:44:19 - 1.56 +++ nc.19 Jan 2011 21:10:44 - @@ -40,7 +40,7 @@ .Op Fl O Ar length .Op Fl P Ar proxy_username .Op Fl p Ar source_port -.Op Fl s Ar source_ip_address +.Op Fl s Ar source .Op Fl T Ar ToS .Op Fl V Ar rtable .Op Fl w Ar timeout @@ -49,7 +49,7 @@ .Fl x Ar proxy_address Ns Oo : Ns .Ar port Oc .Xc Oc -.Op Ar hostname +.Op Ar destination .Op Ar port .Ek .Sh DESCRIPTION @@ -57,8 +57,10 @@ The .Nm (or .Nm netcat ) -utility is used for just about anything under the sun involving TCP -or UDP. +utility is used for just about anything under the sun involving TCP, +UDP, or +.Ux Ns -domain +sockets. It can open TCP connections, send UDP packets, listen on arbitrary TCP and UDP ports, do port scanning, and deal with both IPv4 and IPv6. @@ -153,7 +155,7 @@ instead of sequentially within a range o assigns them. .It Fl S Enables the RFC 2385 TCP MD5 signature option. -.It Fl s Ar source_ip_address +.It Fl s Ar source Specifies the IP of the interface which is used to send the packets. For .Ux Ns -domain @@ -234,7 +236,7 @@ If the protocol is not specified, SOCKS Requests that .Nm should connect to -.Ar hostname +.Ar destination using a proxy at .Ar proxy_address and @@ -252,16 +254,22 @@ It is an error to use this option in con option. .El .Pp -.Ar hostname +.Ar destination can be a numerical IP address or a symbolic hostname (unless the .Fl n option is given). -In general, a hostname must be specified, +In general, a destination must be specified, unless the .Fl l option is given (in which case the local host is used). +For +.Ux Ns -domain +sockets, a destination is required and is the socket path to connect to +(or listen on if the +.Fl l +option is given). .Pp .Ar port can be a single integer or a range of ports. @@ -270,8 +278,7 @@ In general, a destination port must be specified, unless the .Fl U -option is given -(in which case a socket must be specified). +option is given. .Sh CLIENT/SERVER MODEL It is quite simple to build a very basic client/server model using .Nm . @@ -404,7 +411,7 @@ IP for the local end of the connection: .Pp Create and listen on a .Ux Ns -domain -socket: +stream socket: .Pp .Dl $ nc -lU /var/tmp/dsocket .Pp Index: netcat.c === RCS file: /cvs/src/usr.bin/nc/netcat.c,v retrieving revision 1.99 diff -u -p -r1.99 netcat.c --- netcat.c8 Jan 2011 00:44:19 - 1.99 +++ netcat.c9 Jan 2011 21:10:45 - @@ -930,9 +930,9 @@ usage(int ret) { fprintf(stderr, usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n - \t [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS]\n + \t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n \t [-V rtable] [-w timeout] [-X proxy_protocol]\n - \t [-x proxy_address[:port]] [hostname] [port]\n); + \t [-x proxy_address[:port]] [destination] [port]\n); if (ret) exit(1); }
Re: nc -U -u (Unix datagram socket support)
Not sure I count as a network developer but this looks fine to me. On Sun, Jan 09, 2011 at 01:15:51PM -0800, Jeremy Evans wrote: jmc@ and I discussed these man page changes. He's OK with this patch, but would like another network developer to approve. So, looking for OKs. Jeremy Index: nc.1 === RCS file: /cvs/src/usr.bin/nc/nc.1,v retrieving revision 1.56 diff -u -p -r1.56 nc.1 --- nc.1 8 Jan 2011 00:44:19 - 1.56 +++ nc.1 9 Jan 2011 21:10:44 - @@ -40,7 +40,7 @@ .Op Fl O Ar length .Op Fl P Ar proxy_username .Op Fl p Ar source_port -.Op Fl s Ar source_ip_address +.Op Fl s Ar source .Op Fl T Ar ToS .Op Fl V Ar rtable .Op Fl w Ar timeout @@ -49,7 +49,7 @@ .Fl x Ar proxy_address Ns Oo : Ns .Ar port Oc .Xc Oc -.Op Ar hostname +.Op Ar destination .Op Ar port .Ek .Sh DESCRIPTION @@ -57,8 +57,10 @@ The .Nm (or .Nm netcat ) -utility is used for just about anything under the sun involving TCP -or UDP. +utility is used for just about anything under the sun involving TCP, +UDP, or +.Ux Ns -domain +sockets. It can open TCP connections, send UDP packets, listen on arbitrary TCP and UDP ports, do port scanning, and deal with both IPv4 and IPv6. @@ -153,7 +155,7 @@ instead of sequentially within a range o assigns them. .It Fl S Enables the RFC 2385 TCP MD5 signature option. -.It Fl s Ar source_ip_address +.It Fl s Ar source Specifies the IP of the interface which is used to send the packets. For .Ux Ns -domain @@ -234,7 +236,7 @@ If the protocol is not specified, SOCKS Requests that .Nm should connect to -.Ar hostname +.Ar destination using a proxy at .Ar proxy_address and @@ -252,16 +254,22 @@ It is an error to use this option in con option. .El .Pp -.Ar hostname +.Ar destination can be a numerical IP address or a symbolic hostname (unless the .Fl n option is given). -In general, a hostname must be specified, +In general, a destination must be specified, unless the .Fl l option is given (in which case the local host is used). +For +.Ux Ns -domain +sockets, a destination is required and is the socket path to connect to +(or listen on if the +.Fl l +option is given). .Pp .Ar port can be a single integer or a range of ports. @@ -270,8 +278,7 @@ In general, a destination port must be specified, unless the .Fl U -option is given -(in which case a socket must be specified). +option is given. .Sh CLIENT/SERVER MODEL It is quite simple to build a very basic client/server model using .Nm . @@ -404,7 +411,7 @@ IP for the local end of the connection: .Pp Create and listen on a .Ux Ns -domain -socket: +stream socket: .Pp .Dl $ nc -lU /var/tmp/dsocket .Pp Index: netcat.c === RCS file: /cvs/src/usr.bin/nc/netcat.c,v retrieving revision 1.99 diff -u -p -r1.99 netcat.c --- netcat.c 8 Jan 2011 00:44:19 - 1.99 +++ netcat.c 9 Jan 2011 21:10:45 - @@ -930,9 +930,9 @@ usage(int ret) { fprintf(stderr, usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n - \t [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS]\n + \t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n \t [-V rtable] [-w timeout] [-X proxy_protocol]\n - \t [-x proxy_address[:port]] [hostname] [port]\n); + \t [-x proxy_address[:port]] [destination] [port]\n); if (ret) exit(1); }
Re: nc -U -u (Unix datagram socket support)
On Thu, Jan 06, 2011 at 03:32:17PM -0800, Jeremy Evans wrote: This patch adds unix datagram socket support to nc(1). It's basically the same patch I sent last June (see http://marc.info/?l=openbsd-techm=127627296925965w=2), but updated for -current. Tested on amd64. Doesn't appear to cause any regressions to existing support, tested with unix stream and IP stream and datagram sockets. Looking for OKs. Jeremy Hmm, ISTR I meant to look at this ages ago but it got lost, sorry. So you are overloading -u to mean UDP without -l and datagram with -l? I guess this makes sense, but we need man page changes? Index: atomicio.c === RCS file: /cvs/src/usr.bin/nc/atomicio.c,v retrieving revision 1.9 diff -u -p -r1.9 atomicio.c --- atomicio.c7 Sep 2007 14:50:44 - 1.9 +++ atomicio.c6 Jan 2011 21:48:04 - @@ -53,7 +53,7 @@ atomicio(ssize_t (*f) (int, void *, size case -1: if (errno == EINTR) continue; - if (errno == EAGAIN) { + if ((errno == EAGAIN) || (errno == ENOBUFS)) { (void)poll(pfd, 1, -1); continue; } Hmm. atomicio is used all over the place, but I guess this is necessary. Index: netcat.c === RCS file: /cvs/src/usr.bin/nc/netcat.c,v retrieving revision 1.98 diff -u -p -r1.98 netcat.c --- netcat.c 3 Jul 2010 04:44:51 - 1.98 +++ netcat.c 6 Jan 2011 21:48:04 - @@ -89,6 +89,7 @@ u_int rtableid; int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; void atelnet(int, unsigned char *, unsigned int); void build_ports(char *); @@ -99,6 +100,7 @@ intremote_connect(const char *, const c int socks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); int udptest(int); +int unix_bind(char *); int unix_connect(char *); int unix_listen(char *); void set_common_sockopts(int); @@ -241,8 +243,6 @@ main(int argc, char *argv[]) /* Cruft to make sure options are clean, and used properly. */ if (argv[0] !argv[1] family == AF_UNIX) { - if (uflag) - errx(1, cannot use -u and -U); host = argv[0]; uport = NULL; } else if (argv[0] !argv[1]) { @@ -265,6 +265,18 @@ main(int argc, char *argv[]) if (!lflag kflag) errx(1, must use -l with -k); + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) uflag !lflag) { + if(pflag) { + unix_dg_tmp_socket = pflag; + } else { + if((unix_dg_tmp_socket = (char *)malloc(19)) == NULL) + errx(1, not enough memory); Style nit: space between if and (. + strlcpy(unix_dg_tmp_socket, /tmp/nc.XX, 19); + mktemp(unix_dg_tmp_socket); What if this fails? + } + } + /* Initialize addrinfo structure. */ if (family != AF_UNIX) { memset(hints, 0, sizeof(struct addrinfo)); @@ -307,8 +319,12 @@ main(int argc, char *argv[]) int connfd; ret = 0; - if (family == AF_UNIX) - s = unix_listen(host); + if (family == AF_UNIX) { + if(uflag) + s = unix_bind(host); + else + s = unix_listen(host); + } /* Allow only one connection at a time, but stay alive. */ for (;;) { @@ -337,17 +353,19 @@ main(int argc, char *argv[]) if (rv 0) err(1, connect); - connfd = s; + readwrite(s); } else { len = sizeof(cliaddr); connfd = accept(s, (struct sockaddr *)cliaddr, len); + readwrite(connfd); + close(connfd); } - readwrite(connfd); - close(connfd); if (family != AF_UNIX) close(s); + else if (uflag) + connect(s, NULL, 0); Likewise. if (!kflag) break; @@ -361,6 +379,8 @@ main(int argc, char *argv[]) } else ret = 1; + if(uflag) +
Re: nc -U -u (Unix datagram socket support)
On 01/07 09:31, Nicholas Marriott wrote: On Thu, Jan 06, 2011 at 03:32:17PM -0800, Jeremy Evans wrote: This patch adds unix datagram socket support to nc(1). It's basically the same patch I sent last June (see http://marc.info/?l=openbsd-techm=127627296925965w=2), but updated for -current. Tested on amd64. Doesn't appear to cause any regressions to existing support, tested with unix stream and IP stream and datagram sockets. Looking for OKs. Jeremy Hmm, ISTR I meant to look at this ages ago but it got lost, sorry. So you are overloading -u to mean UDP without -l and datagram with -l? I guess this makes sense, but we need man page changes? If you mean -U instead of -l, yes. -u without -U is IP UDP, -u with -U is unix datagram. The man page doesn't say you can't use -u and -U together, and it doesn't say that -U means unix stream sockets, though that is currently all that -U supports. However, I think that making some clarifications to the man page would helpful. Responses inline and new diff at the end. Index: netcat.c === RCS file: /cvs/src/usr.bin/nc/netcat.c,v retrieving revision 1.98 diff -u -p -r1.98 netcat.c --- netcat.c3 Jul 2010 04:44:51 - 1.98 +++ netcat.c6 Jan 2011 21:48:04 - @@ -89,6 +89,7 @@ u_int rtableid; int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; void atelnet(int, unsigned char *, unsigned int); void build_ports(char *); @@ -99,6 +100,7 @@ int remote_connect(const char *, const c intsocks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); intudptest(int); +intunix_bind(char *); intunix_connect(char *); intunix_listen(char *); void set_common_sockopts(int); @@ -241,8 +243,6 @@ main(int argc, char *argv[]) /* Cruft to make sure options are clean, and used properly. */ if (argv[0] !argv[1] family == AF_UNIX) { - if (uflag) - errx(1, cannot use -u and -U); host = argv[0]; uport = NULL; } else if (argv[0] !argv[1]) { @@ -265,6 +265,18 @@ main(int argc, char *argv[]) if (!lflag kflag) errx(1, must use -l with -k); + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) uflag !lflag) { + if(pflag) { + unix_dg_tmp_socket = pflag; + } else { + if((unix_dg_tmp_socket = (char *)malloc(19)) == NULL) + errx(1, not enough memory); Style nit: space between if and (. OK. My diff was bad about that, so I fixed the other cases as well. + strlcpy(unix_dg_tmp_socket, /tmp/nc.XX, 19); + mktemp(unix_dg_tmp_socket); What if this fails? You're right, a failure of mktemp should definitely be checked. + } + } + /* Initialize addrinfo structure. */ if (family != AF_UNIX) { memset(hints, 0, sizeof(struct addrinfo)); @@ -307,8 +319,12 @@ main(int argc, char *argv[]) int connfd; ret = 0; - if (family == AF_UNIX) - s = unix_listen(host); + if (family == AF_UNIX) { + if(uflag) + s = unix_bind(host); + else + s = unix_listen(host); + } /* Allow only one connection at a time, but stay alive. */ for (;;) { @@ -337,17 +353,19 @@ main(int argc, char *argv[]) if (rv 0) err(1, connect); - connfd = s; + readwrite(s); } else { len = sizeof(cliaddr); connfd = accept(s, (struct sockaddr *)cliaddr, len); + readwrite(connfd); + close(connfd); } - readwrite(connfd); - close(connfd); if (family != AF_UNIX) close(s); + else if (uflag) + connect(s, NULL, 0); Likewise. Correct, this should be checked as well. if (!kflag) break; @@ -361,6 +379,8 @@ main(int argc, char *argv[]) } else ret = 1; + if(uflag) + unlink(unix_dg_tmp_socket); Shouldn't this have the same condition as above? The condition when the
Re: nc -U -u (Unix datagram socket support)
On Fri, Jan 07, 2011 at 08:48:20AM -0800, Jeremy Evans wrote: On 01/07 09:31, Nicholas Marriott wrote: On Thu, Jan 06, 2011 at 03:32:17PM -0800, Jeremy Evans wrote: This patch adds unix datagram socket support to nc(1). It's basically the same patch I sent last June (see http://marc.info/?l=openbsd-techm=127627296925965w=2), but updated for -current. Tested on amd64. Doesn't appear to cause any regressions to existing support, tested with unix stream and IP stream and datagram sockets. Looking for OKs. Jeremy Hmm, ISTR I meant to look at this ages ago but it got lost, sorry. So you are overloading -u to mean UDP without -l and datagram with -l? I guess this makes sense, but we need man page changes? If you mean -U instead of -l, yes. -u without -U is IP UDP, -u with -U is unix datagram. The man page doesn't say you can't use -u and -U together, and it doesn't say that -U means unix stream sockets, though that is currently all that -U supports. However, I think that making some clarifications to the man page would helpful. Yes, sorry, I meant -U. This mostly looks fine to me, a few comments: I don't much like using mktemp at all. How about just plain requiring -s with -Uu? Do you actually hit the ENOBUFS condition in atomicio.c? Responses inline and new diff at the end. Index: netcat.c === RCS file: /cvs/src/usr.bin/nc/netcat.c,v retrieving revision 1.98 diff -u -p -r1.98 netcat.c --- netcat.c 3 Jul 2010 04:44:51 - 1.98 +++ netcat.c 6 Jan 2011 21:48:04 - @@ -89,6 +89,7 @@ u_int rtableid; int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; void atelnet(int, unsigned char *, unsigned int); void build_ports(char *); @@ -99,6 +100,7 @@ intremote_connect(const char *, const c int socks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); int udptest(int); +int unix_bind(char *); int unix_connect(char *); int unix_listen(char *); void set_common_sockopts(int); @@ -241,8 +243,6 @@ main(int argc, char *argv[]) /* Cruft to make sure options are clean, and used properly. */ if (argv[0] !argv[1] family == AF_UNIX) { - if (uflag) - errx(1, cannot use -u and -U); host = argv[0]; uport = NULL; } else if (argv[0] !argv[1]) { @@ -265,6 +265,18 @@ main(int argc, char *argv[]) if (!lflag kflag) errx(1, must use -l with -k); + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) uflag !lflag) { + if(pflag) { + unix_dg_tmp_socket = pflag; + } else { + if((unix_dg_tmp_socket = (char *)malloc(19)) == NULL) + errx(1, not enough memory); Style nit: space between if and (. OK. My diff was bad about that, so I fixed the other cases as well. + strlcpy(unix_dg_tmp_socket, /tmp/nc.XX, 19); + mktemp(unix_dg_tmp_socket); What if this fails? You're right, a failure of mktemp should definitely be checked. + } + } + /* Initialize addrinfo structure. */ if (family != AF_UNIX) { memset(hints, 0, sizeof(struct addrinfo)); @@ -307,8 +319,12 @@ main(int argc, char *argv[]) int connfd; ret = 0; - if (family == AF_UNIX) - s = unix_listen(host); + if (family == AF_UNIX) { + if(uflag) + s = unix_bind(host); + else + s = unix_listen(host); + } /* Allow only one connection at a time, but stay alive. */ for (;;) { @@ -337,17 +353,19 @@ main(int argc, char *argv[]) if (rv 0) err(1, connect); - connfd = s; + readwrite(s); } else { len = sizeof(cliaddr); connfd = accept(s, (struct sockaddr *)cliaddr, len); + readwrite(connfd); + close(connfd); } - readwrite(connfd); - close(connfd); if (family != AF_UNIX) close(s); + else if (uflag) + connect(s, NULL, 0); Likewise. Correct, this should be checked as well. if (!kflag)
Re: nc -U -u (Unix datagram socket support)
On 01/07 06:21, Nicholas Marriott wrote: On Fri, Jan 07, 2011 at 08:48:20AM -0800, Jeremy Evans wrote: On 01/07 09:31, Nicholas Marriott wrote: On Thu, Jan 06, 2011 at 03:32:17PM -0800, Jeremy Evans wrote: This patch adds unix datagram socket support to nc(1). It's basically the same patch I sent last June (see http://marc.info/?l=openbsd-techm=127627296925965w=2), but updated for -current. Tested on amd64. Doesn't appear to cause any regressions to existing support, tested with unix stream and IP stream and datagram sockets. Looking for OKs. Jeremy Hmm, ISTR I meant to look at this ages ago but it got lost, sorry. So you are overloading -u to mean UDP without -l and datagram with -l? I guess this makes sense, but we need man page changes? If you mean -U instead of -l, yes. -u without -U is IP UDP, -u with -U is unix datagram. The man page doesn't say you can't use -u and -U together, and it doesn't say that -U means unix stream sockets, though that is currently all that -U supports. However, I think that making some clarifications to the man page would helpful. Yes, sorry, I meant -U. This mostly looks fine to me, a few comments: I don't much like using mktemp at all. How about just plain requiring -s with -Uu? It's annoying to the user to have to specify it when they won't usually care. If you are worried about security, guenther@ thought this usage was secure: http://marc.info/?l=openbsd-techm=120299257422367w=2 I'd prefer we always use a random socket over forcing the user to specify one, but I thinking giving the user choice is best, just like we give them choice of sending address in the IP case. Do you actually hit the ENOBUFS condition in atomicio.c? Yes. That's the only reason I knew to add it. Jeremy
Re: nc -U -u (Unix datagram socket support)
On 01/07 07:31, Nicholas Marriott wrote: On Fri, Jan 07, 2011 at 10:52:18AM -0800, Jeremy Evans wrote: On 01/07 06:21, Nicholas Marriott wrote: Two further minor comments: - Can the mktemp buffer be on the stack rather than malloc()d? Sure. - I think the man page should mention it creates a file in /tmp (or mktemp). Makes sense. OK to commit this diff, which contains the above changes?: Index: atomicio.c === RCS file: /cvs/src/usr.bin/nc/atomicio.c,v retrieving revision 1.9 diff -u -p -r1.9 atomicio.c --- atomicio.c 7 Sep 2007 14:50:44 - 1.9 +++ atomicio.c 6 Jan 2011 21:48:04 - @@ -53,7 +53,7 @@ atomicio(ssize_t (*f) (int, void *, size case -1: if (errno == EINTR) continue; - if (errno == EAGAIN) { + if ((errno == EAGAIN) || (errno == ENOBUFS)) { (void)poll(pfd, 1, -1); continue; } Index: nc.1 === RCS file: /cvs/src/usr.bin/nc/nc.1,v retrieving revision 1.55 diff -u -p -r1.55 nc.1 --- nc.125 Jul 2010 07:51:39 - 1.55 +++ nc.17 Jan 2011 20:08:35 - @@ -155,6 +155,10 @@ assigns them. Enables the RFC 2385 TCP MD5 signature option. .It Fl s Ar source_ip_address Specifies the IP of the interface which is used to send the packets. +For +.Ux Ns -domain +datagram sockets, specifies the local temporary socket file +to create and use so that datagrams can be received. It is an error to use this option in conjunction with the .Fl l option. @@ -179,6 +183,15 @@ Specifies to use sockets. .It Fl u Use UDP instead of the default option of TCP. +For +.Ux Ns -domain +sockets, use a datagram socket instead of a stream socket. +If a +.Ux Ns -domain +socket is used, a temporary receiving socket is created in /tmp unless +you specify one with the +.Fl s +flag. .It Fl V Ar rtable Set the routing table to be used. The default is 0. Index: netcat.c === RCS file: /cvs/src/usr.bin/nc/netcat.c,v retrieving revision 1.98 diff -u -p -r1.98 netcat.c --- netcat.c3 Jul 2010 04:44:51 - 1.98 +++ netcat.c7 Jan 2011 20:03:37 - @@ -62,6 +62,7 @@ #define PORT_MAX 65535 #define PORT_MAX_LEN 6 +#define UNIX_DG_TMP_SOCKET_SIZE19 /* Command Line Options */ intdflag; /* detached, no stdin */ @@ -89,6 +90,7 @@ u_int rtableid; int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; void atelnet(int, unsigned char *, unsigned int); void build_ports(char *); @@ -99,6 +101,7 @@ int remote_connect(const char *, const c intsocks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); intudptest(int); +intunix_bind(char *); intunix_connect(char *); intunix_listen(char *); void set_common_sockopts(int); @@ -117,6 +120,7 @@ main(int argc, char *argv[]) char *proxy; const char *errstr, *proxyhost = , *proxyport = NULL; struct addrinfo proxyhints; + char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; ret = 1; s = 0; @@ -241,8 +245,6 @@ main(int argc, char *argv[]) /* Cruft to make sure options are clean, and used properly. */ if (argv[0] !argv[1] family == AF_UNIX) { - if (uflag) - errx(1, cannot use -u and -U); host = argv[0]; uport = NULL; } else if (argv[0] !argv[1]) { @@ -265,6 +267,19 @@ main(int argc, char *argv[]) if (!lflag kflag) errx(1, must use -l with -k); + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) uflag !lflag) { + if (sflag) { + unix_dg_tmp_socket = sflag; + } else { + strlcpy(unix_dg_tmp_socket_buf, /tmp/nc.XX, + UNIX_DG_TMP_SOCKET_SIZE); + if (mktemp(unix_dg_tmp_socket_buf) == NULL) + err(1, mktemp); + unix_dg_tmp_socket = unix_dg_tmp_socket_buf; + } + } + /* Initialize addrinfo structure. */ if (family != AF_UNIX) { memset(hints, 0, sizeof(struct addrinfo)); @@ -307,8 +322,12 @@ main(int argc, char *argv[]) int connfd; ret = 0; - if (family == AF_UNIX) - s = unix_listen(host); + if (family == AF_UNIX) { + if (uflag) + s = unix_bind(host); +
Re: nc -U -u (Unix datagram socket support)
On Fri, Jan 07, 2011 at 12:13:43PM -0800, Jeremy Evans wrote: Index: nc.1 === RCS file: /cvs/src/usr.bin/nc/nc.1,v retrieving revision 1.55 diff -u -p -r1.55 nc.1 --- nc.1 25 Jul 2010 07:51:39 - 1.55 +++ nc.1 7 Jan 2011 20:08:35 - @@ -155,6 +155,10 @@ assigns them. Enables the RFC 2385 TCP MD5 signature option. .It Fl s Ar source_ip_address Specifies the IP of the interface which is used to send the packets. +For +.Ux Ns -domain +datagram sockets, specifies the local temporary socket file +to create and use so that datagrams can be received. so is source_ip_address a bad choice of name for datagram sockets? It is an error to use this option in conjunction with the .Fl l option. @@ -179,6 +183,15 @@ Specifies to use sockets. .It Fl u Use UDP instead of the default option of TCP. +For +.Ux Ns -domain +sockets, use a datagram socket instead of a stream socket. +If a +.Ux Ns -domain +socket is used, a temporary receiving socket is created in /tmp unless you should probably use .Pa /tmp +you specify one with the +.Fl s +flag. ...unless the -s option/flag is used/given/specified. (we try to avoid 2nd person narrative in man pages) i still think the name of the -s arg is now misleading. jmc .It Fl V Ar rtable Set the routing table to be used. The default is 0.
Re: nc -U -u (Unix datagram socket support)
On Fri, Jan 07, 2011 at 01:03:19PM -0700, Theo de Raadt wrote: Well, I'm less worried about security and also about the fact mktemp is deprecated so I don't think adding new uses of it is not ideal. mktemp(3) is not deprecated. It continues to be safe to use for directory creation or other atomic file creations (success or failure; the other party opening it is subject to a race as long as it waits to know that the parent (nc) says it has in fact created it successfully). It is possible to loop. Go through our source tree. There are things calling mktemp(3) on purpose -- in places where mkstemp(3) cannot be used. Fair enough. The man page seems a bit over strong, how about this? Index: mktemp.3 === RCS file: /cvs/src/lib/libc/stdio/mktemp.3,v retrieving revision 1.45 diff -u -p -r1.45 mktemp.3 --- mktemp.327 Dec 2010 21:18:44 - 1.45 +++ mktemp.37 Jan 2011 20:23:00 - @@ -72,12 +72,12 @@ does not actually create the temporary f opportunity during which another process can open the file instead. Because of this race condition, .Fn mktemp -should not be used in new code. +should not be used where +.Fn mkstemp +can be used instead. .Fn mktemp was marked as a legacy interface in -.St -p1003.1-2001 -and may be removed in a future release of -.Ox . +.St -p1003.1-2001 . .Pp The .Fn mkstemp
Re: nc -U -u (Unix datagram socket support)
Fair enough. The man page seems a bit over strong, how about this? Index: mktemp.3 === RCS file: /cvs/src/lib/libc/stdio/mktemp.3,v retrieving revision 1.45 diff -u -p -r1.45 mktemp.3 --- mktemp.3 27 Dec 2010 21:18:44 - 1.45 +++ mktemp.3 7 Jan 2011 20:23:00 - @@ -72,12 +72,12 @@ does not actually create the temporary f opportunity during which another process can open the file instead. Because of this race condition, .Fn mktemp -should not be used in new code. +should not be used where +.Fn mkstemp +can be used instead. That looks good. .Fn mktemp was marked as a legacy interface in -.St -p1003.1-2001 -and may be removed in a future release of -.Ox . +.St -p1003.1-2001 . That looks good too. I think that whoever wrote that saw smoking something. So there is a mkdtemp(), but where is the AF_UNIX version? I think it is important that people who do use mktemp(3) realize that they must loop over failure (creating a new path each time), and they need to use a do not use the path from elsewhere unless the code that opens it returns success paradigm. mktemp(3) just provides a potentially unique name; the expected gaurantees must be supplied by the caller.
Re: nc -U -u (Unix datagram socket support)
On Fri, Jan 07, 2011 at 01:32:27PM -0700, Theo de Raadt wrote: I think it is important that people who do use mktemp(3) realize that they must loop over failure (creating a new path each time), and they need to use a do not use the path from elsewhere unless the code that opens it returns success paradigm. mktemp(3) just provides a potentially unique name; the expected gaurantees must be supplied by the caller. It is also important that the caller provides enough XXX to actually have a chance to finish the loop against a motivated concurrent user, especially when using something like /tmp. Joerg
Re: nc -U -u (Unix datagram socket support)
It is also important that the caller provides enough XXX to actually have a chance to finish the loop against a motivated concurrent user, especially when using something like /tmp. For us that is not really a problem since our mktemp is using 63 possibilities per slot. Stem selection remains important, too. 250047 for XXX 15752961 for 992436543 for Personally I would recommend 10 X's.
Re: nc -U -u (Unix datagram socket support)
On Fri, Jan 07, 2011 at 01:32:27PM -0700, Theo de Raadt wrote: So there is a mkdtemp(), but where is the AF_UNIX version? Well it wouldn't be big thing to add but from a quick look it seems like nc would be the only user. I think it is important that people who do use mktemp(3) realize that they must loop over failure (creating a new path each time), and they need to use a do not use the path from elsewhere unless the code that opens it returns success paradigm. mktemp(3) just provides a potentially unique name; the expected gaurantees must be supplied by the caller. Maybe with something like this: +Where +.Fn mktemp +must be used, callers should ensure they detect failure when subsequently +attempting to create the file and generate a new name by calling +.Fn mktemp +again before retrying. Or maybe another example in the examples section. Index: mktemp.3 === RCS file: /cvs/src/lib/libc/stdio/mktemp.3,v retrieving revision 1.45 diff -u -p -r1.45 mktemp.3 --- mktemp.327 Dec 2010 21:18:44 - 1.45 +++ mktemp.37 Jan 2011 21:15:11 - @@ -72,12 +72,18 @@ does not actually create the temporary f opportunity during which another process can open the file instead. Because of this race condition, .Fn mktemp -should not be used in new code. +should not be used where +.Fn mkstemp +can be used instead. +Where +.Fn mktemp +must be used, callers should ensure they detect failure when subsequently +attempting to create the file and generate a new name by calling +.Fn mktemp +again before retrying. .Fn mktemp was marked as a legacy interface in -.St -p1003.1-2001 -and may be removed in a future release of -.Ox . +.St -p1003.1-2001 . .Pp The .Fn mkstemp
Re: nc -U -u (Unix datagram socket support)
ok nicm, but you should save jmc the effort and trim the lines you left with trailing spaces in the man page ;-). On Fri, Jan 07, 2011 at 12:13:43PM -0800, Jeremy Evans wrote: On 01/07 07:31, Nicholas Marriott wrote: On Fri, Jan 07, 2011 at 10:52:18AM -0800, Jeremy Evans wrote: On 01/07 06:21, Nicholas Marriott wrote: Two further minor comments: - Can the mktemp buffer be on the stack rather than malloc()d? Sure. - I think the man page should mention it creates a file in /tmp (or mktemp). Makes sense. OK to commit this diff, which contains the above changes?: Index: atomicio.c === RCS file: /cvs/src/usr.bin/nc/atomicio.c,v retrieving revision 1.9 diff -u -p -r1.9 atomicio.c --- atomicio.c7 Sep 2007 14:50:44 - 1.9 +++ atomicio.c6 Jan 2011 21:48:04 - @@ -53,7 +53,7 @@ atomicio(ssize_t (*f) (int, void *, size case -1: if (errno == EINTR) continue; - if (errno == EAGAIN) { + if ((errno == EAGAIN) || (errno == ENOBUFS)) { (void)poll(pfd, 1, -1); continue; } Index: nc.1 === RCS file: /cvs/src/usr.bin/nc/nc.1,v retrieving revision 1.55 diff -u -p -r1.55 nc.1 --- nc.1 25 Jul 2010 07:51:39 - 1.55 +++ nc.1 7 Jan 2011 20:08:35 - @@ -155,6 +155,10 @@ assigns them. Enables the RFC 2385 TCP MD5 signature option. .It Fl s Ar source_ip_address Specifies the IP of the interface which is used to send the packets. +For +.Ux Ns -domain +datagram sockets, specifies the local temporary socket file +to create and use so that datagrams can be received. It is an error to use this option in conjunction with the .Fl l option. @@ -179,6 +183,15 @@ Specifies to use sockets. .It Fl u Use UDP instead of the default option of TCP. +For +.Ux Ns -domain +sockets, use a datagram socket instead of a stream socket. +If a +.Ux Ns -domain +socket is used, a temporary receiving socket is created in /tmp unless +you specify one with the +.Fl s +flag. .It Fl V Ar rtable Set the routing table to be used. The default is 0. Index: netcat.c === RCS file: /cvs/src/usr.bin/nc/netcat.c,v retrieving revision 1.98 diff -u -p -r1.98 netcat.c --- netcat.c 3 Jul 2010 04:44:51 - 1.98 +++ netcat.c 7 Jan 2011 20:03:37 - @@ -62,6 +62,7 @@ #define PORT_MAX 65535 #define PORT_MAX_LEN 6 +#define UNIX_DG_TMP_SOCKET_SIZE 19 /* Command Line Options */ int dflag; /* detached, no stdin */ @@ -89,6 +90,7 @@ u_int rtableid; int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; void atelnet(int, unsigned char *, unsigned int); void build_ports(char *); @@ -99,6 +101,7 @@ intremote_connect(const char *, const c int socks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); int udptest(int); +int unix_bind(char *); int unix_connect(char *); int unix_listen(char *); void set_common_sockopts(int); @@ -117,6 +120,7 @@ main(int argc, char *argv[]) char *proxy; const char *errstr, *proxyhost = , *proxyport = NULL; struct addrinfo proxyhints; + char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; ret = 1; s = 0; @@ -241,8 +245,6 @@ main(int argc, char *argv[]) /* Cruft to make sure options are clean, and used properly. */ if (argv[0] !argv[1] family == AF_UNIX) { - if (uflag) - errx(1, cannot use -u and -U); host = argv[0]; uport = NULL; } else if (argv[0] !argv[1]) { @@ -265,6 +267,19 @@ main(int argc, char *argv[]) if (!lflag kflag) errx(1, must use -l with -k); + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) uflag !lflag) { + if (sflag) { + unix_dg_tmp_socket = sflag; + } else { + strlcpy(unix_dg_tmp_socket_buf, /tmp/nc.XX, + UNIX_DG_TMP_SOCKET_SIZE); + if (mktemp(unix_dg_tmp_socket_buf) == NULL) + err(1, mktemp); + unix_dg_tmp_socket = unix_dg_tmp_socket_buf; + } + } + /* Initialize addrinfo structure. */ if (family != AF_UNIX) { memset(hints, 0, sizeof(struct addrinfo)); @@ -307,8 +322,12 @@ main(int argc, char *argv[]) int connfd; ret = 0; -
nc -U -u (Unix datagram socket support)
This patch adds unix datagram socket support to nc(1). It's basically the same patch I sent last June (see http://marc.info/?l=openbsd-techm=127627296925965w=2), but updated for -current. Tested on amd64. Doesn't appear to cause any regressions to existing support, tested with unix stream and IP stream and datagram sockets. Looking for OKs. Jeremy Index: atomicio.c === RCS file: /cvs/src/usr.bin/nc/atomicio.c,v retrieving revision 1.9 diff -u -p -r1.9 atomicio.c --- atomicio.c 7 Sep 2007 14:50:44 - 1.9 +++ atomicio.c 6 Jan 2011 21:48:04 - @@ -53,7 +53,7 @@ atomicio(ssize_t (*f) (int, void *, size case -1: if (errno == EINTR) continue; - if (errno == EAGAIN) { + if ((errno == EAGAIN) || (errno == ENOBUFS)) { (void)poll(pfd, 1, -1); continue; } Index: netcat.c === RCS file: /cvs/src/usr.bin/nc/netcat.c,v retrieving revision 1.98 diff -u -p -r1.98 netcat.c --- netcat.c3 Jul 2010 04:44:51 - 1.98 +++ netcat.c6 Jan 2011 21:48:04 - @@ -89,6 +89,7 @@ u_int rtableid; int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; void atelnet(int, unsigned char *, unsigned int); void build_ports(char *); @@ -99,6 +100,7 @@ int remote_connect(const char *, const c intsocks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); intudptest(int); +intunix_bind(char *); intunix_connect(char *); intunix_listen(char *); void set_common_sockopts(int); @@ -241,8 +243,6 @@ main(int argc, char *argv[]) /* Cruft to make sure options are clean, and used properly. */ if (argv[0] !argv[1] family == AF_UNIX) { - if (uflag) - errx(1, cannot use -u and -U); host = argv[0]; uport = NULL; } else if (argv[0] !argv[1]) { @@ -265,6 +265,18 @@ main(int argc, char *argv[]) if (!lflag kflag) errx(1, must use -l with -k); + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) uflag !lflag) { + if(pflag) { + unix_dg_tmp_socket = pflag; + } else { + if((unix_dg_tmp_socket = (char *)malloc(19)) == NULL) + errx(1, not enough memory); + strlcpy(unix_dg_tmp_socket, /tmp/nc.XX, 19); + mktemp(unix_dg_tmp_socket); + } + } + /* Initialize addrinfo structure. */ if (family != AF_UNIX) { memset(hints, 0, sizeof(struct addrinfo)); @@ -307,8 +319,12 @@ main(int argc, char *argv[]) int connfd; ret = 0; - if (family == AF_UNIX) - s = unix_listen(host); + if (family == AF_UNIX) { + if(uflag) + s = unix_bind(host); + else + s = unix_listen(host); + } /* Allow only one connection at a time, but stay alive. */ for (;;) { @@ -337,17 +353,19 @@ main(int argc, char *argv[]) if (rv 0) err(1, connect); - connfd = s; + readwrite(s); } else { len = sizeof(cliaddr); connfd = accept(s, (struct sockaddr *)cliaddr, len); + readwrite(connfd); + close(connfd); } - readwrite(connfd); - close(connfd); if (family != AF_UNIX) close(s); + else if (uflag) + connect(s, NULL, 0); if (!kflag) break; @@ -361,6 +379,8 @@ main(int argc, char *argv[]) } else ret = 1; + if(uflag) + unlink(unix_dg_tmp_socket); exit(ret); } else { @@ -421,18 +441,19 @@ main(int argc, char *argv[]) } /* - * unix_connect() - * Returns a socket connected to a local unix socket. Returns -1 on failure. + * unix_bind() + * Returns a unix socket bound to the given path */ int -unix_connect(char *path) +unix_bind(char *path) { struct
Re: nc -U -u (Unix datagram socket support)
On Thu, Jan 6, 2011 at 6:32 PM, Jeremy Evans jer...@openbsd.org wrote: This patch adds unix datagram socket support to nc(1). It's basically the same patch I sent last June (see http://marc.info/?l=openbsd-techm=127627296925965w=2), but updated for -current. Tested on amd64. Doesn't appear to cause any regressions to existing support, tested with unix stream and IP stream and datagram sockets. Looking for OKs. Why is the socket name specified via -p for datagrams or possibly random? Shouldn't this be just like the stream unix code? + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) uflag !lflag) { + if(pflag) { + unix_dg_tmp_socket = pflag; + } else { + if((unix_dg_tmp_socket = (char *)malloc(19)) == NULL) + errx(1, not enough memory); + strlcpy(unix_dg_tmp_socket, /tmp/nc.XX, 19); + mktemp(unix_dg_tmp_socket); + } + } +
Re: nc -U -u (Unix datagram socket support)
On 01/06 07:07, Ted Unangst wrote: On Thu, Jan 6, 2011 at 6:32 PM, Jeremy Evans jer...@openbsd.org wrote: This patch adds unix datagram socket support to nc(1). ?It's basically the same patch I sent last June (see http://marc.info/?l=openbsd-techm=127627296925965w=2), but updated for -current. Tested on amd64. ?Doesn't appear to cause any regressions to existing support, tested with unix stream and IP stream and datagram sockets. Looking for OKs. Why is the socket name specified via -p for datagrams or possibly random? Shouldn't this be just like the stream unix code? I believe that for unix stream sockets, you don't need to have a sending socket file created, while you do for datagram sockets, as otherwise you can't have a bidirectional connection. I have no problem with always using a random sending socket file, and ignoring -p in the unix datagram case, if you think that is best. Thinking more about it, -s would be more appropriate than -p anyway if you did want to specify the source socket. Jeremy + ? ? ? /* Get name of temporary socket for unix datagram client */ + ? ? ? if ((family == AF_UNIX) uflag !lflag) { + ? ? ? ? ? ? ? if(pflag) { + ? ? ? ? ? ? ? ? ? ? ? unix_dg_tmp_socket = pflag; + ? ? ? ? ? ? ? } else { + ? ? ? ? ? ? ? ? ? ? ? if((unix_dg_tmp_socket = (char *)malloc(19)) == NULL) + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? errx(1, not enough memory); + ? ? ? ? ? ? ? ? ? ? ? strlcpy(unix_dg_tmp_socket, /tmp/nc.XX, 19); + ? ? ? ? ? ? ? ? ? ? ? mktemp(unix_dg_tmp_socket); + ? ? ? ? ? ? ? } + ? ? ? } +
Re: nc -U -u (Unix datagram socket support)
On Thu, Jan 6, 2011 at 7:19 PM, Jeremy Evans jer...@openbsd.org wrote: I believe that for unix stream sockets, you don't need to have a sending socket file created, while you do for datagram sockets, as otherwise you can't have a bidirectional connection. I have no problem with always using a random sending socket file, and ignoring -p in the unix datagram case, if you think that is best. Thinking more about it, -s would be more appropriate than -p anyway if you did want to specify the source socket. The part that's confusing me is, who is at the other end of this tmp socket? How do they know about it?
Re: nc -U -u (Unix datagram socket support)
On 01/06 08:56, Ted Unangst wrote: On Thu, Jan 6, 2011 at 7:19 PM, Jeremy Evans jer...@openbsd.org wrote: I believe that for unix stream sockets, you don't need to have a sending socket file created, while you do for datagram sockets, as otherwise you can't have a bidirectional connection. I have no problem with always using a random sending socket file, and ignoring -p in the unix datagram case, if you think that is best. Thinking more about it, -s would be more appropriate than -p anyway if you did want to specify the source socket. The part that's confusing me is, who is at the other end of this tmp socket? How do they know about it? With a stream socket where you are acting as a client, you don't need a temporary socket created, because a stream socket is bidirectional. If you send a datagram to a server listening on a unix datagram socket, there is no way for the server program to respond to you unless the sending program is also bound to a socket. So with this patch, if you are operating nc in client mode and sending a datagram to a unix datagram socket, nc binds a temporary unix datagram socket so that you can receive responses. guenther@ agreed back in 2008 that it was necessary to create a temporary socket if you want bidirectional communication, see http://marc.info/?l=openbsd-techm=120299257422367w=2. He also mentioned that it might be beneficial to implement two modes, one providing bidirectional and one providing unidirectional, but I have not implemented that (yet). Jeremy