diff -urN mpd-3.18.orig/src/iface.c mpd-3.18/src/iface.c --- mpd-3.18.orig/src/iface.c Tue May 4 22:12:28 2004 +++ mpd-3.18/src/iface.c Mon Oct 10 22:17:00 2005 @@ -310,9 +310,11 @@ #endif /* Turn on interface traffic flow */ - if (Enabled(&iface->options, IFACE_CONF_TCPMSSFIX)) + if (Enabled(&iface->options, IFACE_CONF_TCPMSSFIX)) { NgFuncConfigBPF(bund, BPF_MODE_MSSFIX); - else + if (gNgTcpMssFix) + NgFuncConfigTCPMSS(bund, MAXMSS(iface->mtu)); + } else NgFuncConfigBPF(bund, BPF_MODE_ON); /* Send any cached packets */ diff -urN mpd-3.18.orig/src/main.c mpd-3.18/src/main.c --- mpd-3.18.orig/src/main.c Tue May 4 22:12:28 2004 +++ mpd-3.18/src/main.c Mon Oct 10 22:16:03 2005 @@ -64,6 +64,8 @@ "Show version information" }, { 0, 'h', "help", "", "Show usage information" }, + { 0, 'm', "mssfix", "", + "Use ng_tcpmssfix instead of internal one" }, }; #define OPTLIST_SIZE (sizeof(OptList) / sizeof(*OptList)) @@ -81,6 +83,7 @@ Bund *gBundles; int gNumLinks; int gNumBundles; + int gNgTcpMssFix; const char *gConfigFile = CONF_FILE; const char *gConfDirectory = PATH_CONF_DIR; @@ -514,6 +517,9 @@ exit(EX_NORMAL); case 'h': Usage(EX_NORMAL); + case 'm': + gNgTcpMssFix = TRUE; + return(0); default: assert(0); } diff -urN mpd-3.18.orig/src/ngfunc.c mpd-3.18/src/ngfunc.c --- mpd-3.18.orig/src/ngfunc.c Tue May 4 22:12:28 2004 +++ mpd-3.18/src/ngfunc.c Mon Oct 10 22:16:03 2005 @@ -28,6 +28,7 @@ #include #include #include +#include /* * DEFINITIONS @@ -272,6 +273,22 @@ goto fail; } + if (gNgTcpMssFix) { + /* Add a tcpmss node to the bpf node on the "tcpmssfix" hook */ + snprintf(path, sizeof(path), "%s.%s", MPD_HOOK_PPP, NG_PPP_HOOK_INET); + snprintf(mp.type, sizeof(mp.type), "%s", NG_TCPMSS_NODE_TYPE); + snprintf(mp.ourhook, sizeof(mp.ourhook), "%s", BPF_HOOK_TCPMSS); + snprintf(mp.peerhook, sizeof(mp.peerhook), "%s", BPF_HOOK_TCPMSS); + if (NgSendMsg(b->csock, path, + NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) { + Log(LG_ERR, ("[%s] can't create %s node: %s", + b->name, NG_TCPMSS_NODE_TYPE, strerror(errno))); + goto fail; + } + /* Initial configuration of ng_tcpmss */ + NgFuncConfigTCPMSS(b, 0); + } + /* Configure bpf(8) node */ NgFuncConfigBPF(b, BPF_MODE_OFF); @@ -523,7 +540,11 @@ snprintf(hp->ifNotMatch, sizeof(hp->ifNotMatch), "%s", BPF_HOOK_IFACE); break; case BPF_MODE_MSSFIX: - snprintf(hp->ifMatch, sizeof(hp->ifMatch), "%s", BPF_HOOK_MPD); + if (gNgTcpMssFix) { + snprintf(hp->ifMatch, sizeof(hp->ifMatch), "%s", BPF_HOOK_TCPMSS); + } else { + snprintf(hp->ifMatch, sizeof(hp->ifMatch), "%s", BPF_HOOK_MPD); + } snprintf(hp->ifNotMatch, sizeof(hp->ifNotMatch), "%s", BPF_HOOK_IFACE); break; default: @@ -558,13 +579,43 @@ assert(0); } - /* Set new program on the BPF_HOOK_IFACE hook */ + /* Set new program on the BPF_HOOK_MPD hook */ if (NgSendMsg(b->csock, path, NGM_BPF_COOKIE, NGM_BPF_SET_PROGRAM, hp, NG_BPF_HOOKPROG_SIZE(hp->bpf_prog_len)) < 0) { Log(LG_ERR, ("[%s] can't set %s node program: %s", b->name, NG_BPF_NODE_TYPE, strerror(errno))); DoExit(EX_ERRDEAD); } + + if (gNgTcpMssFix) { + /* Configure the hook on the TCPMSS node side of the BPF node */ + memset(&u, 0, sizeof(u)); + snprintf(hp->thisHook, sizeof(hp->thisHook), "%s", BPF_HOOK_TCPMSS); + hp->bpf_prog_len = NOMATCH_PROG_LEN; + memcpy(&hp->bpf_prog, + &gNoMatchProg, NOMATCH_PROG_LEN * sizeof(*gNoMatchProg)); + switch (mode) { + case BPF_MODE_OFF: + case BPF_MODE_DEMAND: + case BPF_MODE_ON: + memset(&hp->ifMatch, 0, sizeof(hp->ifMatch)); + memset(&hp->ifNotMatch, 0, sizeof(hp->ifNotMatch)); + break; + case BPF_MODE_MSSFIX: + snprintf(hp->ifMatch, sizeof(hp->ifMatch), "%s", BPF_HOOK_IFACE); + snprintf(hp->ifNotMatch, sizeof(hp->ifNotMatch), "%s", BPF_HOOK_IFACE); + break; + default: + assert(0); + } + /* Set new program on the BPF_HOOK_TCPMSS hook */ + if (NgSendMsg(b->csock, path, NGM_BPF_COOKIE, + NGM_BPF_SET_PROGRAM, hp, NG_BPF_HOOKPROG_SIZE(hp->bpf_prog_len)) < 0) { + Log(LG_ERR, ("[%s] can't set %s node program: %s", + b->name, NG_BPF_NODE_TYPE, strerror(errno))); + DoExit(EX_ERRDEAD); + } + } } /* @@ -945,5 +996,32 @@ buf, strerror(errno))); } +/* + * NgFuncConfigTCPMSS() + * + * Configure the tcpmss node to reduce MSS to given value. + */ +void +NgFuncConfigTCPMSS(Bund b, int maxMSS) +{ + char path[NG_PATHLEN + 1]; + struct ng_tcpmss_config tcpmsscfg; + /* Get absolute path to node */ + snprintf(path, sizeof(path), "%s:%s.%s", b->iface.ifname, + NG_IFACE_HOOK_INET, BPF_HOOK_TCPMSS); + + /* Send configuration message */ + memset(&tcpmsscfg,0,sizeof(tcpmsscfg)); + snprintf(tcpmsscfg.inHook, sizeof(tcpmsscfg.inHook), "%s", BPF_HOOK_TCPMSS); + snprintf(tcpmsscfg.outHook, sizeof(tcpmsscfg.outHook), "%s", BPF_HOOK_TCPMSS); + tcpmsscfg.maxMSS = maxMSS; + + if (NgSendMsg(bund->csock, path, NGM_TCPMSS_COOKIE, + NGM_TCPMSS_CONFIG, &tcpmsscfg, sizeof(tcpmsscfg)) < 0) { + Log(LG_ERR, ("[%s] can't set %s node program: %s", + b->name, NG_TCPMSS_NODE_TYPE, strerror(errno))); + DoExit(EX_ERRDEAD); + } +} diff -urN mpd-3.18.orig/src/ngfunc.h mpd-3.18/src/ngfunc.h --- mpd-3.18.orig/src/ngfunc.h Tue May 4 22:12:28 2004 +++ mpd-3.18/src/ngfunc.h Mon Oct 10 22:16:03 2005 @@ -26,6 +26,7 @@ #define BPF_HOOK_PPP "ppp" #define BPF_HOOK_IFACE "iface" #define BPF_HOOK_MPD "mpd" + #define BPF_HOOK_TCPMSS "tcpmssfix" #define BPF_MODE_OFF 0 /* no BPF node traffic gets through */ #define BPF_MODE_ON 1 /* normal BPF node traffic flow */ @@ -49,6 +50,7 @@ const char *path2, const char *hook2); extern int NgFuncDisconnect(const char *path, const char *hook); extern int NgFuncShutdownNode(Bund b, const char *label, const char *path); + extern void NgFuncConfigTCPMSS(Bund b, int maxMSS); #endif diff -urN mpd-3.18.orig/src/ppp.h mpd-3.18/src/ppp.h --- mpd-3.18.orig/src/ppp.h Tue May 4 22:12:28 2004 +++ mpd-3.18/src/ppp.h Mon Oct 10 22:16:03 2005 @@ -84,6 +84,7 @@ extern int gNumLinks; /* Total number of links */ extern int gNumBundles; /* Total number of bundles */ + extern int gNgTcpMssFix; /* Use ng_tcpmss node */ extern Bund bund; /* Current bundle */ extern Link lnk; /* Current link */