RFC {get,set}socktopt SO_DONTFRAGMENT
Mario Sergio Fujikawa Ferreira
lioux at FreeBSD.org
Fri May 5 03:38:13 UTC 2006
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
-------------- next part --------------
--- /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;
More information about the freebsd-arch
mailing list