No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / vstream_tweak.c
blob4519acf03c0ed655ee8ac06cab0036daa467f294
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* vstream_tweak 3
6 /* SUMMARY
7 /* performance tweaks
8 /* SYNOPSIS
9 /* #include <vstream.h>
11 /* VSTREAM *vstream_tweak_sock(stream)
12 /* VSTREAM *stream;
14 /* VSTREAM *vstream_tweak_tcp(stream)
15 /* VSTREAM *stream;
16 /* DESCRIPTION
17 /* vstream_tweak_sock() does a best effort to boost your
18 /* network performance on the specified generic stream.
20 /* vstream_tweak_tcp() does a best effort to boost your
21 /* Internet performance on the specified TCP stream.
23 /* Arguments:
24 /* .IP stream
25 /* The stream being boosted.
26 /* DIAGNOSTICS
27 /* Panics: interface violations.
28 /* LICENSE
29 /* .ad
30 /* .fi
31 /* The Secure Mailer license must be distributed with this software.
32 /* AUTHOR(S)
33 /* Wietse Venema
34 /* IBM T.J. Watson Research
35 /* P.O. Box 704
36 /* Yorktown Heights, NY 10598, USA
37 /*--*/
39 /* System library. */
41 #include <sys_defs.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <netinet/tcp.h>
46 /* Utility library. */
48 #include <msg.h>
49 #include <vstream.h>
51 /* Application-specific. */
53 #ifdef HAS_IPV6
54 #define SOCKADDR_STORAGE struct sockaddr_storage
55 #else
56 #define SOCKADDR_STORAGE struct sockaddr
57 #endif
59 /* vstream_tweak_sock - boost your generic network performance */
61 int vstream_tweak_sock(VSTREAM *fp)
63 SOCKADDR_STORAGE ss;
64 struct sockaddr *sa = (struct sockaddr *) & ss;
65 SOCKADDR_SIZE sa_length = sizeof(ss);
66 int ret;
69 * If the caller doesn't know if this socket is AF_LOCAL, AF_INET, etc.,
70 * figure it out for them.
72 if ((ret = getsockname(vstream_fileno(fp), sa, &sa_length)) >= 0) {
73 switch (sa->sa_family) {
74 #ifdef AF_INET6
75 case AF_INET6:
76 #endif
77 case AF_INET:
78 ret = vstream_tweak_tcp(fp);
79 break;
82 return (ret);
85 /* vstream_tweak_tcp - boost your TCP performance */
87 int vstream_tweak_tcp(VSTREAM *fp)
89 const char *myname = "vstream_tweak_tcp";
90 int mss;
91 SOCKOPT_SIZE mss_len = sizeof(mss);
92 int err;
95 * Avoid Nagle delays when VSTREAM buffers are smaller than the MSS.
97 * Forcing TCP_NODELAY to be "always on" would hurt performance in the
98 * common case where VSTREAM buffers are larger than the MSS.
100 * Instead we ask the kernel what the current MSS is, and take appropriate
101 * action. Linux <= 2.2 getsockopt(TCP_MAXSEG) always returns zero (or
102 * whatever value was stored last with setsockopt()).
104 if ((err = getsockopt(vstream_fileno(fp), IPPROTO_TCP, TCP_MAXSEG,
105 (char *) &mss, &mss_len)) < 0) {
106 msg_warn("%s: getsockopt TCP_MAXSEG: %m", myname);
107 return (err);
109 if (msg_verbose)
110 msg_info("%s: TCP_MAXSEG %d", myname, mss);
113 * Fix for recent Postfix versions: increase the VSTREAM buffer size if
114 * the VSTREAM buffer is smaller than the MSS. Note: the MSS may change
115 * when the route changes and IP path MTU discovery is turned on, so we
116 * choose a somewhat larger buffer.
118 #ifdef VSTREAM_CTL_BUFSIZE
119 if (mss > 0) {
120 if (mss < INT_MAX / 2)
121 mss *= 2;
122 vstream_control(fp,
123 VSTREAM_CTL_BUFSIZE, (ssize_t) mss,
124 VSTREAM_CTL_END);
128 * Workaround for older Postfix versions: turn on TCP_NODELAY if the
129 * VSTREAM buffer size is smaller than the MSS.
131 #else
132 if (mss > VSTREAM_BUFSIZE) {
133 int nodelay = 1;
135 if ((err = setsockopt(vstream_fileno(fp), IPPROTO_TCP, TCP_NODELAY,
136 (char *) &nodelay, sizeof(nodelay))) < 0)
137 msg_warn("%s: setsockopt TCP_NODELAY: %m", myname);
139 #endif
140 return (err);