From owner-freebsd-arch@FreeBSD.ORG Fri May 5 03:38:13 2006 Return-Path: X-Original-To: freebsd-arch@FreeBSD.org Delivered-To: freebsd-arch@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 040BA16A401 for ; Fri, 5 May 2006 03:38:13 +0000 (UTC) (envelope-from lioux@FreeBSD.org) Received: from vette.gigo.com (vette.gigo.com [216.218.228.114]) by mx1.FreeBSD.org (Postfix) with ESMTP id BCD8543D45 for ; Fri, 5 May 2006 03:38:12 +0000 (GMT) (envelope-from lioux@FreeBSD.org) Received: from 200.193.235.83 (unknown [200.193.235.83]) by vette.gigo.com (Postfix) with ESMTP id 55BE95762 for ; Thu, 4 May 2006 20:38:11 -0700 (PDT) Received: (qmail 76859 invoked by uid 1001); 5 May 2006 00:37:26 -0300 Message-ID: <20060505033749.76815.qmail@exxodus.fedaykin.here> Date: Fri, 5 May 2006 00:37:26 -0300 From: Mario Sergio Fujikawa Ferreira To: freebsd-arch@FreeBSD.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="VbJkn9YxBvnuCH5J" Content-Disposition: inline User-Agent: Mutt/1.5.11 Cc: Subject: RFC {get,set}socktopt SO_DONTFRAGMENT X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 May 2006 03:38:13 -0000 --VbJkn9YxBvnuCH5J Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, I would like to propose a new socket option: SO_DONTFRAGMENT on the lines of IP_DONTFRAG. I was trying to tell a socket that it should not fragment the packets. However, I found out that I could only do it if I had a "struct socket". If I had a "struct socket" I could set INP_DONTFRAG which would solve all my problems. Unfortunaly, I only had a file descriptor fd from a int fd = socket(...); invocation. it is a shame that there is no way to tell a socket fd that it should not fragment packets on userland (it is possible on kernel space). That is why I wrote this little modification: 1) Added SO_DONTFRAGMENT option to src/sys/sys/socket.h 2) Added SO_DONTFRAGMENT handling to src/sys/kern/uipc_socket.c. Actually, it sets either (struct inpcb *)->inp_flags &= INP_DONTFRAG; or (struct inpcb *)->inp_flags |= ~INP_DONTFRAG; I would like to know if the code is correct and what do you think about this approach. I do think this should be handled by {get,set}sockopt(2) instead of a ioctl(2) because it is specific to sockets. Moreover, I think this is a very useful option. For instance, I want to add this to net-im/libjingle to emulate the behavior of both windows and linux. The patch is attached. It can also be found at http://people.freebsd.org/~lioux/patch-sockopt-dontfragment Regards, -- Mario S F Ferreira - DF - Brazil - "I guess this is a signature." feature, n: a documented bug | bug, n: an undocumented feature --VbJkn9YxBvnuCH5J Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch-sockopt-dontfragment --- /usr/src/sys/sys/socket.h.orig Thu May 4 12:56:39 2006 +++ /usr/src/sys/sys/socket.h Fri May 5 00:14:41 2006 @@ -118,6 +118,7 @@ #define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */ #define SO_BINTIME 0x2000 /* timestamp received dgram traffic */ #endif +#define SO_DONTFRAGMENT 0x4000 /* don't fragment packet */ /* * Additional options, not kept in so_options. --- /usr/src/sys/kern/uipc_socket.c.orig Thu May 4 13:00:50 2006 +++ /usr/src/sys/kern/uipc_socket.c Fri May 5 00:11:39 2006 @@ -1553,6 +1553,7 @@ #ifdef MAC struct mac extmac; #endif + struct inpcb *inp = sotoinpcb(so); error = 0; if (sopt->sopt_level != SOL_SOCKET) { @@ -1594,6 +1595,7 @@ case SO_TIMESTAMP: case SO_BINTIME: case SO_NOSIGPIPE: + case SO_DONTFRAGMENT: error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) @@ -1603,6 +1605,23 @@ so->so_options |= sopt->sopt_name; else so->so_options &= ~sopt->sopt_name; + + switch (sopt->sopt_name) { + +#define OPTSET(bit) do { \ + INP_LOCK(inp); \ + if (optval) \ + inp->inp_flags |= bit; \ + else \ + inp->inp_flags &= ~bit; \ + INP_UNLOCK(inp); \ +} while (0) + + case SO_DONTFRAGMENT: + OPTSET(INP_DONTFRAG); + break; + } + SOCK_UNLOCK(so); break; --VbJkn9YxBvnuCH5J--