1 /*++
2 /* NAME
3 /*	inet_windowsize 3
4 /* SUMMARY
5 /*	TCP window scaling control
6 /* SYNOPSIS
7 /*	#include <iostuff.h>
8 /*
9 /*	int	inet_windowsize;
10 /*
11 /*	void	set_inet_windowsize(sock, windowsize)
12 /*	int	sock;
13 /*	int	windowsize;
14 /* DESCRIPTION
15 /*	set_inet_windowsize() overrides the default TCP window size
16 /*	with the specified value. When called before listen() or
17 /*	accept(), this works around broken infrastructure that
18 /*	mis-handles TCP window scaling options.
19 /*
20 /*	The global inet_windowsize variable is available for other
21 /*	routines to remember that they wish to override the default
22 /*	TCP window size. The variable is not accessed by the
23 /*	set_inet_windowsize() function itself.
24 /*
25 /*	Arguments:
26 /* .IP sock
27 /*	TCP communication endpoint, before the connect(2) or listen(2) call.
28 /* .IP windowsize
29 /*	The preferred TCP window size. This must be > 0.
30 /* DIAGNOSTICS
31 /*	Panic: interface violation.
32 /*	Warnings: some error return from setsockopt().
33 /* LICENSE
34 /* .ad
35 /* .fi
36 /*	The Secure Mailer license must be distributed with this software.
37 /* AUTHOR(S)
38 /*	Wietse Venema
39 /*	IBM T.J. Watson Research
40 /*	P.O. Box 704
41 /*	Yorktown Heights, NY 10598, USA
42 /*--*/
43 
44 /* System libraries. */
45 
46 #include <sys_defs.h>
47 #include <sys/socket.h>
48 
49 /* Utility library. */
50 
51 #include <msg.h>
52 #include <iostuff.h>
53 
54 /* Application storage. */
55 
56  /*
57   * Tunable to work around broken routers.
58   */
59 int     inet_windowsize = 0;
60 
61 /* set_inet_windowsize - set TCP send/receive window size */
62 
set_inet_windowsize(int sock,int windowsize)63 void    set_inet_windowsize(int sock, int windowsize)
64 {
65 
66     /*
67      * Sanity check.
68      */
69     if (windowsize <= 0)
70 	msg_panic("inet_windowsize: bad window size %d", windowsize);
71 
72     /*
73      * Generic implementation: set the send and receive buffer size before
74      * listen() or connect().
75      */
76     if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *) &windowsize,
77 		   sizeof(windowsize)) < 0)
78 	msg_warn("setsockopt SO_SNDBUF %d: %m", windowsize);
79     if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *) &windowsize,
80 		   sizeof(windowsize)) < 0)
81 	msg_warn("setsockopt SO_RCVBUF %d: %m", windowsize);
82 }
83