summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2000-11-28 13:18:35 +0000
committerbrian <brian@FreeBSD.org>2000-11-28 13:18:35 +0000
commit36c3bc9fdd02adc5f96a3e76e563a04a7c574260 (patch)
treeb961d5c39b6396fc1d98e9e69cf6ede026166c4d /usr.sbin
parent288e8299bbed979c25cb497be766dfaada3da557 (diff)
downloadFreeBSD-src-36c3bc9fdd02adc5f96a3e76e563a04a7c574260.zip
FreeBSD-src-36c3bc9fdd02adc5f96a3e76e563a04a7c574260.tar.gz
Add ``enable/disable tcpmssfixup'', defaulting to enabled.
Suggested by: julian Hijacked from: ru (ports/net/tcpmssd)
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/ppp/Makefile4
-rw-r--r--usr.sbin/ppp/bundle.c28
-rw-r--r--usr.sbin/ppp/bundle.h8
-rw-r--r--usr.sbin/ppp/command.c4
-rw-r--r--usr.sbin/ppp/physical.c2
-rw-r--r--usr.sbin/ppp/ppp.88
-rw-r--r--usr.sbin/ppp/ppp.8.m48
-rw-r--r--usr.sbin/ppp/tcpmss.c168
-rw-r--r--usr.sbin/ppp/tcpmss.h29
-rw-r--r--usr.sbin/ppp/tun.c6
-rw-r--r--usr.sbin/ppp/tun.h2
11 files changed, 245 insertions, 22 deletions
diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile
index 046a3b9..fe89221 100644
--- a/usr.sbin/ppp/Makefile
+++ b/usr.sbin/ppp/Makefile
@@ -5,8 +5,8 @@ SRCS= acf.c arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chat.c \
command.c datalink.c deflate.c defs.c exec.c filter.c fsm.c hdlc.c \
iface.c ip.c ipcp.c iplist.c lcp.c link.c log.c lqr.c main.c \
mbuf.c mp.c pap.c physical.c pred.c probe.c prompt.c proto.c route.c \
- server.c sig.c slcompress.c sync.c systems.c tcp.c throughput.c \
- timer.c tty.c tun.c udp.c vjcomp.c
+ server.c sig.c slcompress.c sync.c systems.c tcp.c tcpmss.c \
+ throughput.c timer.c tty.c tun.c udp.c vjcomp.c
CFLAGS+=-Wall
LDADD+= -lcrypt -lmd -lutil -lz
DPADD+= ${LIBCRYPT} ${LIBMD} ${LIBUTIL} ${LIBZ}
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index 3ca0f81..30627a1 100644
--- a/usr.sbin/ppp/bundle.c
+++ b/usr.sbin/ppp/bundle.c
@@ -797,6 +797,7 @@ bundle_Create(const char *prefix, int type, int unit)
log_Printf(LogPHASE, "Using interface: %s\n", ifname);
bundle.bandwidth = 0;
+ bundle.mtu = 1500;
bundle.routing_seq = 0;
bundle.phase = PHASE_DEAD;
bundle.CleaningUp = 0;
@@ -812,7 +813,7 @@ bundle_Create(const char *prefix, int type, int unit)
bundle.cfg.idle.min_timeout = 0;
*bundle.cfg.auth.name = '\0';
*bundle.cfg.auth.key = '\0';
- bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK |
+ bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK | OPT_TCPMSSFIXUP |
OPT_THROUGHPUT | OPT_UTMP;
*bundle.cfg.label = '\0';
bundle.cfg.mtu = DEF_MTU;
@@ -1232,9 +1233,11 @@ bundle_ShowStatus(struct cmdargs const *arg)
optval(arg->bundle, OPT_PROXY));
prompt_Printf(arg->prompt, " Proxyall: %s\n",
optval(arg->bundle, OPT_PROXYALL));
- prompt_Printf(arg->prompt, " Throughput: %-20.20s",
+ prompt_Printf(arg->prompt, " TCPMSS Fixup: %-20.20s",
+ optval(arg->bundle, OPT_TCPMSSFIXUP));
+ prompt_Printf(arg->prompt, " Throughput: %s\n",
optval(arg->bundle, OPT_THROUGHPUT));
- prompt_Printf(arg->prompt, " Utmp Logging: %s\n",
+ prompt_Printf(arg->prompt, " Utmp Logging: %-20.20s",
optval(arg->bundle, OPT_UTMP));
prompt_Printf(arg->prompt, " Iface-Alias: %s\n",
optval(arg->bundle, OPT_IFACEALIAS));
@@ -1924,10 +1927,10 @@ void
bundle_CalculateBandwidth(struct bundle *bundle)
{
struct datalink *dl;
- int mtu, sp;
+ int sp;
bundle->bandwidth = 0;
- mtu = 0;
+ bundle->mtu = 0;
for (dl = bundle->links; dl; dl = dl->next)
if (dl->state == DATALINK_OPEN) {
if ((sp = dl->mp.bandwidth) == 0 &&
@@ -1937,7 +1940,7 @@ bundle_CalculateBandwidth(struct bundle *bundle)
else
bundle->bandwidth += sp;
if (!bundle->ncp.mp.active) {
- mtu = dl->physical->link.lcp.his_mru;
+ bundle->mtu = dl->physical->link.lcp.his_mru;
break;
}
}
@@ -1946,19 +1949,20 @@ bundle_CalculateBandwidth(struct bundle *bundle)
bundle->bandwidth = 115200; /* Shrug */
if (bundle->ncp.mp.active)
- mtu = bundle->ncp.mp.peer_mrru;
- else if (!mtu)
- mtu = 1500;
+ bundle->mtu = bundle->ncp.mp.peer_mrru;
+ else if (!bundle->mtu)
+ bundle->mtu = 1500;
#ifndef NORADIUS
- if (bundle->radius.valid && bundle->radius.mtu && bundle->radius.mtu < mtu) {
+ if (bundle->radius.valid && bundle->radius.mtu &&
+ bundle->radius.mtu < bundle->mtu) {
log_Printf(LogLCP, "Reducing MTU to radius value %lu\n",
bundle->radius.mtu);
- mtu = bundle->radius.mtu;
+ bundle->mtu = bundle->radius.mtu;
}
#endif
- tun_configure(bundle, mtu);
+ tun_configure(bundle);
}
void
diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h
index 9ea2971..96acab1 100644
--- a/usr.sbin/ppp/bundle.h
+++ b/usr.sbin/ppp/bundle.h
@@ -42,8 +42,9 @@
#define OPT_PROXY 0x0040
#define OPT_PROXYALL 0x0080
#define OPT_SROUTES 0x0100
-#define OPT_THROUGHPUT 0x0200
-#define OPT_UTMP 0x0400
+#define OPT_TCPMSSFIXUP 0x0200
+#define OPT_THROUGHPUT 0x0400
+#define OPT_UTMP 0x0800
#define MAX_ENDDISC_CLASS 5
@@ -72,6 +73,7 @@ struct bundle {
} dev;
u_long bandwidth; /* struct tuninfo speed */
+ int mtu; /* struct tuninfo MTU */
struct iface *iface; /* Interface information */
int routing_seq; /* The current routing sequence number */
@@ -101,7 +103,7 @@ struct bundle {
} auth;
unsigned opt; /* Uses OPT_ bits from above */
char label[50]; /* last thing `load'ed */
- u_short mtu; /* Interface mtu */
+ u_short mtu; /* Required interface MTU */
u_short ifqueue; /* Interface queue size */
struct {
diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c
index 9a62b31..05b25fd 100644
--- a/usr.sbin/ppp/command.c
+++ b/usr.sbin/ppp/command.c
@@ -2531,12 +2531,14 @@ static struct cmdtab const NegotiateCommands[] = {
"disable|enable", (const void *)OPT_PROXYALL},
{"sroutes", NULL, OptSet, LOCAL_AUTH, "Use sticky routes",
"disable|enable", (const void *)OPT_SROUTES},
+ {"tcpmssfixup", "mssfixup", OptSet, LOCAL_AUTH, "Modify MSS options",
+ "disable|enable", (const void *)OPT_TCPMSSFIXUP},
{"throughput", NULL, OptSet, LOCAL_AUTH, "Rolling throughput",
"disable|enable", (const void *)OPT_THROUGHPUT},
{"utmp", NULL, OptSet, LOCAL_AUTH, "Log connections in utmp",
"disable|enable", (const void *)OPT_UTMP},
-#define OPT_MAX 10 /* accept/deny allowed below and not above */
+#define OPT_MAX 11 /* accept/deny allowed below and not above */
{"acfcomp", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX,
"Address & Control field compression", "accept|deny|disable|enable",
diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c
index c0979a9..3d7811f 100644
--- a/usr.sbin/ppp/physical.c
+++ b/usr.sbin/ppp/physical.c
@@ -99,6 +99,7 @@
#ifndef NOATM
#include "atm.h"
#endif
+#include "tcpmss.h"
#define PPPOTCPLINE "ppp"
@@ -1052,6 +1053,7 @@ physical_SetupStack(struct physical *p, const char *who, int how)
link_Stack(&p->link, &lqrlayer);
link_Stack(&p->link, &ccplayer);
link_Stack(&p->link, &vjlayer);
+ link_Stack(&p->link, &tcpmsslayer);
#ifndef NONAT
link_Stack(&p->link, &natlayer);
#endif
diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8
index 5b91959..a3b34d4 100644
--- a/usr.sbin/ppp/ppp.8
+++ b/usr.sbin/ppp/ppp.8
@@ -3007,6 +3007,14 @@ Disabling this option will prevent the re-application of sticky routes,
although the
.Sq stick route
list will still be maintained.
+.It Op tcp Ns Xo
+.No mssfixup
+.Xc
+Default: Enabled.
+This option tells
+.Nm
+to adjust outgoing TCP SYN packets so that the maximum receive segment
+size is not greater than the amount allowed by the interface MTU.
.It throughput
Default: Enabled.
This option tells
diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4
index 5b91959..a3b34d4 100644
--- a/usr.sbin/ppp/ppp.8.m4
+++ b/usr.sbin/ppp/ppp.8.m4
@@ -3007,6 +3007,14 @@ Disabling this option will prevent the re-application of sticky routes,
although the
.Sq stick route
list will still be maintained.
+.It Op tcp Ns Xo
+.No mssfixup
+.Xc
+Default: Enabled.
+This option tells
+.Nm
+to adjust outgoing TCP SYN packets so that the maximum receive segment
+size is not greater than the amount allowed by the interface MTU.
.It throughput
Default: Enabled.
This option tells
diff --git a/usr.sbin/ppp/tcpmss.c b/usr.sbin/ppp/tcpmss.c
new file mode 100644
index 0000000..ed7ef46
--- /dev/null
+++ b/usr.sbin/ppp/tcpmss.c
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (c) 2000 Ruslan Ermilov and Brian Somers <brian@Awfulhak.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+
+#include <termios.h>
+
+#include "layer.h"
+#include "defs.h"
+#include "log.h"
+#include "timer.h"
+#include "fsm.h"
+#include "mbuf.h"
+#include "throughput.h"
+#include "lqr.h"
+#include "hdlc.h"
+#include "lcp.h"
+#include "ccp.h"
+#include "link.h"
+#include "iplist.h"
+#include "slcompress.h"
+#include "ipcp.h"
+#include "filter.h"
+#include "descriptor.h"
+#include "mp.h"
+#ifndef NORADIUS
+#include "radius.h"
+#endif
+#include "bundle.h"
+
+
+/*-
+ * We are in a liberal position about MSS
+ * (RFC 879, section 7).
+ */
+#define MAXMSS(mtu) (mtu - sizeof(struct ip) - sizeof(struct tcphdr))
+
+
+static void MSSFixup(struct tcphdr *, ssize_t, u_int16_t);
+
+
+static struct mbuf *
+tcpmss_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
+ int pri, u_short *proto)
+{
+ struct ip *pip;
+ int hlen, plen;
+
+ if (!Enabled(bundle, OPT_TCPMSSFIXUP))
+ return bp;
+
+ bp = m_pullup(bp);
+ plen = m_length(bp);
+ pip = (struct ip *)MBUF_CTOP(bp);
+ hlen = pip->ip_hl << 2;
+
+ /*
+ * Check for MSS option only for TCP packets with zero fragment offsets
+ * and correct total and header lengths.
+ */
+ if (pip->ip_p == IPPROTO_TCP && (ntohs(pip->ip_off) & IP_OFFMASK) == 0 &&
+ ntohs(pip->ip_len) == plen && hlen <= plen &&
+ plen - hlen >= sizeof(struct tcphdr))
+ MSSFixup((struct tcphdr *)(MBUF_CTOP(bp) + hlen), plen - hlen,
+ MAXMSS(bundle->mtu));
+
+ return bp;
+}
+
+/*-
+ * The following macro is used to update an
+ * internet checksum. "acc" is a 32-bit
+ * accumulation of all the changes to the
+ * checksum (adding in old 16-bit words and
+ * subtracting out new words), and "cksum"
+ * is the checksum value to be updated.
+ */
+#define ADJUST_CHECKSUM(acc, cksum) { \
+ acc += cksum; \
+ if (acc < 0) { \
+ acc = -acc; \
+ acc = (acc >> 16) + (acc & 0xffff); \
+ acc += acc >> 16; \
+ cksum = (u_short) ~acc; \
+ } else { \
+ acc = (acc >> 16) + (acc & 0xffff); \
+ acc += acc >> 16; \
+ cksum = (u_short) acc; \
+ } \
+}
+
+static void
+MSSFixup(struct tcphdr *tc, ssize_t pktlen, u_int16_t maxmss)
+{
+ int hlen, olen, optlen;
+ u_char *opt;
+ u_int16_t *mss;
+ int accumulate;
+
+ hlen = tc->th_off << 2;
+
+ /* Invalid header length or header without options. */
+ if (hlen <= sizeof(struct tcphdr) || hlen > pktlen)
+ return;
+
+ /* MSS option only allowed within SYN packets. */
+ if (!(tc->th_flags & TH_SYN))
+ return;
+
+ for (olen = hlen - sizeof(struct tcphdr), opt = (u_char *)(tc + 1);
+ olen > 0; olen -= optlen, opt += optlen) {
+ if (*opt == TCPOPT_EOL)
+ break;
+ else if (*opt == TCPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = *(opt + 1);
+ if (optlen <= 0 || optlen > olen)
+ break;
+ if (*opt == TCPOPT_MAXSEG) {
+ if (optlen != TCPOLEN_MAXSEG)
+ continue;
+ mss = (u_int16_t *)(opt + 2);
+ if (ntohs(*mss) > maxmss) {
+ log_Printf(LogDEBUG, "MSS: %u -> %u\n",
+ ntohs(*mss), maxmss);
+ accumulate = *mss;
+ *mss = htons(maxmss);
+ accumulate -= *mss;
+ ADJUST_CHECKSUM(accumulate, tc->th_sum);
+ }
+ }
+ }
+ }
+}
+
+struct layer tcpmsslayer = { LAYER_PROTO, "tcpmss", tcpmss_LayerPush, NULL };
diff --git a/usr.sbin/ppp/tcpmss.h b/usr.sbin/ppp/tcpmss.h
new file mode 100644
index 0000000..ffd7b82
--- /dev/null
+++ b/usr.sbin/ppp/tcpmss.h
@@ -0,0 +1,29 @@
+/*-
+ * Copyright (c) 2000 Brian Somers <brian@Awfulhak.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+extern struct layer tcpmsslayer;
diff --git a/usr.sbin/ppp/tun.c b/usr.sbin/ppp/tun.c
index c35894a..d391f49 100644
--- a/usr.sbin/ppp/tun.c
+++ b/usr.sbin/ppp/tun.c
@@ -74,7 +74,7 @@
#include "tun.h"
void
-tun_configure(struct bundle *bundle, int mtu)
+tun_configure(struct bundle *bundle)
{
#ifdef __NetBSD__
struct ifreq ifr;
@@ -88,7 +88,7 @@ tun_configure(struct bundle *bundle, int mtu)
}
sprintf(ifr.ifr_name, "tun%d", bundle->unit);
- ifr.ifr_mtu = mtu;
+ ifr.ifr_mtu = bundle->mtu;
if (ioctl(s, SIOCSIFMTU, &ifr) < 0)
log_Printf(LogERROR, "tun_configure: ioctl(SIOCSIFMTU): %s\n",
strerror(errno));
@@ -99,7 +99,7 @@ tun_configure(struct bundle *bundle, int mtu)
memset(&info, '\0', sizeof info);
info.type = IFT_PPP;
- info.mtu = mtu;
+ info.mtu = bundle->mtu;
info.baudrate = bundle->bandwidth;
#ifdef __OpenBSD__
diff --git a/usr.sbin/ppp/tun.h b/usr.sbin/ppp/tun.h
index 06d1ae8..1bb0712 100644
--- a/usr.sbin/ppp/tun.h
+++ b/usr.sbin/ppp/tun.h
@@ -36,4 +36,4 @@ struct tun_data {
struct bundle;
-extern void tun_configure(struct bundle *, int);
+extern void tun_configure(struct bundle *);
OpenPOWER on IntegriCloud