diff -urNp mpd3-cvs.orig/src/chap.c mpd3-cvs/src/chap.c --- mpd3-cvs.orig/src/chap.c Sun May 8 17:54:56 2005 +++ mpd3-cvs/src/chap.c Tue Jul 4 15:23:39 2006 @@ -312,8 +312,10 @@ ChapInput(Mbuf bp) /* Check packet */ if (a->self_to_peer != PROTO_CHAP - || lnk->lcp.phase != PHASE_AUTHENTICATE) + || lnk->lcp.phase != PHASE_AUTHENTICATE) { Log(LG_AUTH, (" Not expected, but that's OK")); + break; + } if (ChapParsePkt(bp, len, peer_name, chap_value, &chap_value_size) < 0) break; @@ -450,8 +452,11 @@ ChapInput(Mbuf bp) /* Check response */ if (a->peer_to_self != PROTO_CHAP - || lnk->lcp.phase != PHASE_AUTHENTICATE) + || lnk->lcp.phase != PHASE_AUTHENTICATE) { Log(LG_AUTH, (" Not expected, but that's OK")); + break; + } + if (ChapParsePkt(bp, len, peer_name, chap_value, &chap_value_size) < 0) { whyFail = AUTH_FAIL_INVALID_PACKET; diff -urNp mpd3-cvs.orig/src/iface.c mpd3-cvs/src/iface.c --- mpd3-cvs.orig/src/iface.c Fri Nov 5 08:31:58 2004 +++ mpd3-cvs/src/iface.c Tue May 23 22:56:53 2006 @@ -20,6 +20,7 @@ #include "netgraph.h" #include "radius.h" #include "util.h" +#include "pptp.h" #include #include #include @@ -29,9 +30,11 @@ #ifdef __DragonFly__ #include #include +#include #else #include #include +#include #endif /* @@ -284,7 +287,12 @@ IfaceUp(struct in_addr self, struct in_a /* Reset bpf node statistics */ memset(&iface->idleStats, 0, sizeof(iface->idleStats)); + if (gEnableTee) { + snprintf(path, sizeof(path), "%s:%s.%s", iface->ifname, + NG_IFACE_HOOK_INET, NG_TEE_HOOK_RIGHT); + } else { snprintf(path, sizeof(path), "%s:%s", iface->ifname, NG_IFACE_HOOK_INET); + } if (NgSendMsg(bund->csock, path, NGM_BPF_COOKIE, NGM_BPF_CLR_STATS, BPF_HOOK_IFACE, sizeof(BPF_HOOK_IFACE)) < 0) Log(LG_ERR, ("[%s] can't clear %s stats: %s", @@ -315,9 +323,11 @@ IfaceUp(struct in_addr self, struct in_a #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 */ @@ -685,11 +695,24 @@ IfaceIpIfaceUp(int ready) ns2buf[0] = '\0'; snprintf(peerbuf, sizeof(peerbuf), "%s", inet_ntoa(iface->peer_addr)); + + if (lnk->phys->type == &gPptpPhysType) { + char pptp_peer[100]; + + snprintf(pptp_peer, sizeof(pptp_peer), "%s", inet_ntoa(*(PptpGetPeerIp()))); + ExecCmd(LG_IFACE, "%s %s inet %s %s %s %s %s %s", + iface->up_script, iface->ifname, inet_ntoa(iface->self_addr), + peerbuf, + *bund->peer_authname ? bund->peer_authname : bund->conf.authname, + ns1buf, ns2buf, + pptp_peer); + } else { ExecCmd(LG_IFACE, "%s %s inet %s %s %s %s %s", iface->up_script, iface->ifname, inet_ntoa(iface->self_addr), peerbuf, *bund->peer_authname ? bund->peer_authname : bund->conf.authname, ns1buf, ns2buf); + } } /* Done */ @@ -837,7 +860,12 @@ IfaceIdleTimeout(void *arg) /* Get updated bpf node traffic statistics */ oldStats = iface->idleStats; + if (gEnableTee) { + snprintf(path, sizeof(path), "%s:%s.%s", iface->ifname, + NG_IFACE_HOOK_INET, NG_TEE_HOOK_RIGHT); + } else { snprintf(path, sizeof(path), "%s:%s", iface->ifname, NG_IFACE_HOOK_INET); + } if (NgSendMsg(bund->csock, path, NGM_BPF_COOKIE, NGM_BPF_GET_STATS, BPF_HOOK_IFACE, sizeof(BPF_HOOK_IFACE)) < 0) { Log(LG_ERR, ("[%s] can't get %s stats: %s", diff -urNp mpd3-cvs.orig/src/link.h mpd3-cvs/src/link.h --- mpd3-cvs.orig/src/link.h Sun Jul 25 00:26:20 2004 +++ mpd3-cvs/src/link.h Tue May 23 22:56:53 2006 @@ -99,6 +99,8 @@ u_int64_t runts; /* Too short MP fragments */ u_int64_t dupFragments; /* MP frames with duplicate seq # */ u_int64_t dropFragments; /* MP fragments we had to drop */ + u_int64_t sv_xmitOctets; /* update-limit support */ + u_int64_t sv_recvOctets; /* update-limit support */ }; typedef struct linkstat *LinkStats; diff -urNp mpd3-cvs.orig/src/main.c mpd3-cvs/src/main.c --- mpd3-cvs.orig/src/main.c Sat Oct 11 10:26:13 2003 +++ mpd3-cvs/src/main.c Tue May 23 22:56:53 2006 @@ -64,6 +64,10 @@ "Show version information" }, { 0, 'h', "help", "", "Show usage information" }, + { 0, 't', "tee", "", + "Insert ng_tee into netgraph" }, + { 0, 'm', "mssfix", "", + "Use ng_tcpmss instead of internal one" }, }; #define OPTLIST_SIZE (sizeof(OptList) / sizeof(*OptList)) @@ -81,6 +85,8 @@ Bund *gBundles; int gNumLinks; int gNumBundles; + int gEnableTee = FALSE; + int gNgTcpMssFix; const char *gConfigFile = CONF_FILE; const char *gConfDirectory = PATH_CONF_DIR; @@ -514,6 +520,12 @@ OptApply(Option opt, int ac, char *av[]) exit(EX_NORMAL); case 'h': Usage(EX_NORMAL); + case 't': + gEnableTee = TRUE; + return(0); + case 'm': + gNgTcpMssFix = TRUE; + return(0); default: assert(0); } diff -urNp mpd3-cvs.orig/src/ngfunc.c mpd3-cvs/src/ngfunc.c --- mpd3-cvs.orig/src/ngfunc.c Sun Jul 25 00:26:20 2004 +++ mpd3-cvs/src/ngfunc.c Tue May 23 22:56:53 2006 @@ -29,6 +29,8 @@ #include #include #include +#include +#include #else #include #include @@ -36,6 +38,8 @@ #include #include #include +#include +#include #endif /* @@ -123,18 +127,13 @@ /* A BPF filter that matches TCP SYN packets */ static const struct bpf_insn gTCPSYNProg[] = { - - /* Load IP protocol number and IP header length */ /*00*/ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9), /* A <- IP protocol */ -/*01*/ BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 0), /* X <- header len */ - -/*02*/ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 1, 0), /* -> 04 */ -/*03*/ BPF_STMT(BPF_RET+BPF_K, 0), /* reject packet */ - - /* Protocol is TCP -> accept if TH_SYN bit set */ -/*04*/ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 13), /* A <- TCP flags */ -/*05*/ BPF_STMT(BPF_ALU+BPF_AND+BPF_K, TH_SYN), /* A <- A & TH_SYN */ -/*06*/ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 1, 0), /* compare to zero */ +/*01*/ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 6), /* reject if not TCP */ +/*02*/ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 6), /* A <- fragmentation offset */ +/*03*/ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 4, 0), /* ensure we have TCP hdr */ +/*04*/ BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 0), /* X <- header len */ +/*05*/ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 13), /* A <- TCP flags */ +/*06*/ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, TH_SYN, 0, 1), /* jump if set */ /*07*/ BPF_STMT(BPF_RET+BPF_K, (u_int)-1), /* accept packet */ /*08*/ BPF_STMT(BPF_RET+BPF_K, 0), /* reject packet */ }; @@ -258,17 +257,30 @@ NgFuncInit(Bund b, const char *reqIface) goto fail; } - /* Connect the other side of the bpf node to the iface node */ + /* Connect the other side of the bpf node to the iface or tee node */ snprintf(path, sizeof(path), "%s.%s", MPD_HOOK_PPP, NG_PPP_HOOK_INET); + if (gEnableTee) { + snprintf(cn.path, sizeof(cn.path), "%s:%s", + b->iface.ifname, NG_IFACE_HOOK_INET); + snprintf(cn.peerhook, sizeof(cn.peerhook), "%s", NG_TEE_HOOK_RIGHT); + } else { snprintf(cn.path, sizeof(cn.path), "%s:", b->iface.ifname); - snprintf(cn.ourhook, sizeof(cn.ourhook), "%s", BPF_HOOK_IFACE); snprintf(cn.peerhook, sizeof(cn.peerhook), "%s", NG_IFACE_HOOK_INET); + } + snprintf(cn.ourhook, sizeof(cn.ourhook), "%s", BPF_HOOK_IFACE); + if (NgSendMsg(b->csock, path, NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) { + if (gEnableTee) { + Log(LG_ERR, ("[%s] can't connect %s and %s: %s", + b->name, BPF_HOOK_IFACE, NG_TEE_HOOK_RIGHT, strerror(errno))); + goto fail; + } else { Log(LG_ERR, ("[%s] can't connect %s and %s: %s", b->name, BPF_HOOK_IFACE, NG_IFACE_HOOK_INET, strerror(errno))); goto fail; } + } /* Connect a hook from the bpf node to our socket node */ snprintf(cn.path, sizeof(cn.path), "%s.%s", MPD_HOOK_PPP, NG_PPP_HOOK_INET); @@ -281,6 +293,22 @@ NgFuncInit(Bund b, const char *reqIface) 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); @@ -399,6 +427,7 @@ NgFuncCreateIface(Bund b, const char *if struct nodeinfo *const ni = (struct nodeinfo *)(void *)u.reply.data; struct ngm_rmhook rm; struct ngm_mkpeer mp; + struct ngm_connect cn; int rtn = 0; /* If ifname is not null, create interfaces until it gets created */ @@ -450,6 +479,38 @@ NgFuncCreateIface(Bund b, const char *if snprintf(buf, max, "%s", ni->name); done: + + /* Disconnect temporary hook */ + snprintf(rm.ourhook, sizeof(rm.ourhook), "%s", TEMPHOOK); + if (NgSendMsg(b->csock, ".", + NGM_GENERIC_COOKIE, NGM_RMHOOK, &rm, sizeof(rm)) < 0) { + Log(LG_ERR, ("[%s] can't remove hook %s: %s", + b->name, TEMPHOOK, strerror(errno))); + rtn = -1; + } + + /* Add netgraph tee node to created iface if configured */ + if (gEnableTee && (rtn != -1)) { + /* Create tee node (as a temporary peer of the socket node) */ + snprintf(mp.type, sizeof(mp.type), "%s", NG_TEE_NODE_TYPE); + snprintf(mp.ourhook, sizeof(mp.ourhook), "%s", TEMPHOOK); + snprintf(mp.peerhook, sizeof(mp.peerhook), "%s", NG_TEE_HOOK_RIGHT); + if (NgSendMsg(b->csock, ".", + NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) { + Log(LG_ERR, ("[%s] can't create %s node: %s", + b->name, NG_TEE_NODE_TYPE, strerror(errno))); + return(-1); + } + /* Connect tee and iface nodes */ + snprintf(cn.path, sizeof(cn.path), "%s:", ni->name); + snprintf(cn.ourhook, sizeof(cn.ourhook), "%s", NG_TEE_HOOK_LEFT); + snprintf(cn.peerhook, sizeof(cn.peerhook), "%s", NG_IFACE_HOOK_INET); + if (NgSendMsg(b->csock, TEMPHOOK, + NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) { + Log(LG_ERR, ("[%s] can't connect %s and %s: %s", + b->name, NG_TEE_HOOK_LEFT, NG_IFACE_HOOK_INET, strerror(errno))); + rtn = -1; + } /* Disconnect temporary hook */ snprintf(rm.ourhook, sizeof(rm.ourhook), "%s", TEMPHOOK); if (NgSendMsg(b->csock, ".", @@ -458,6 +519,7 @@ done: b->name, TEMPHOOK, strerror(errno))); rtn = -1; } + } /* Done */ return(rtn); @@ -482,7 +544,12 @@ NgFuncConfigBPF(Bund b, int mode) char path[NG_PATHLEN + 1]; /* Get absolute path to bpf node */ + if (gEnableTee) { + snprintf(path, sizeof(path), "%s:%s.%s", b->iface.ifname, + NG_IFACE_HOOK_INET, NG_TEE_HOOK_RIGHT); + } else { snprintf(path, sizeof(path), "%s:%s", b->iface.ifname, NG_IFACE_HOOK_INET); + } /* First, configure the hook on the interface node side of the BPF node */ memset(&u, 0, sizeof(u)); @@ -532,7 +599,11 @@ NgFuncConfigBPF(Bund b, int mode) snprintf(hp->ifNotMatch, sizeof(hp->ifNotMatch), "%s", BPF_HOOK_IFACE); break; case BPF_MODE_MSSFIX: + 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: @@ -567,13 +638,43 @@ NgFuncConfigBPF(Bund b, int mode) 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); } + } } /* @@ -599,10 +700,23 @@ NgFuncShutdownInternal(Bund b, int iface Bund bund_save; Link lnk_save; int k; + struct ngm_rmhook rm; if (iface) { + if (gEnableTee) { + /* Disconnect tee:right hook */ + snprintf(path, sizeof(path), "%s:%s", + b->iface.ifname, NG_IFACE_HOOK_INET); + snprintf(rm.ourhook, sizeof(rm.ourhook), "%s", NG_TEE_HOOK_RIGHT); + if (NgSendMsg(b->csock, path, + NGM_GENERIC_COOKIE, NGM_RMHOOK, &rm, sizeof(rm)) < 0) { + Log(LG_ERR, ("[%s] can't remove hook %s: %s", + b->name, NG_TEE_HOOK_RIGHT, strerror(errno))); + } + } else { snprintf(path, sizeof(path), "%s:", b->iface.ifname); NgFuncShutdownNode(b, b->name, path); + } } lnk_save = lnk; bund_save = bund; @@ -954,5 +1068,36 @@ NgFuncErr(const char *fmt, ...) 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 */ + if (gEnableTee) + snprintf(path, sizeof(path), "%s:%s.%s.%s", b->iface.ifname, + NG_IFACE_HOOK_INET, NG_TEE_HOOK_RIGHT, BPF_HOOK_TCPMSS); + else + 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 -urNp mpd3-cvs.orig/src/ngfunc.h mpd3-cvs/src/ngfunc.h --- mpd3-cvs.orig/src/ngfunc.h Sun Jul 25 00:26:20 2004 +++ mpd3-cvs/src/ngfunc.h Tue May 23 22:56:53 2006 @@ -30,6 +30,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 */ @@ -53,6 +54,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 -urNp mpd3-cvs.orig/src/ppp.h mpd3-cvs/src/ppp.h --- mpd3-cvs.orig/src/ppp.h Sun Jul 25 00:26:20 2004 +++ mpd3-cvs/src/ppp.h Tue May 23 22:56:53 2006 @@ -88,6 +88,8 @@ extern int gNumLinks; /* Total number of links */ extern int gNumBundles; /* Total number of bundles */ + extern int gEnableTee; /* Insert ng_tee into netgraph */ + extern int gNgTcpMssFix; /* Use ng_tcpmss node */ extern Bund bund; /* Current bundle */ extern Link lnk; /* Current link */ diff -urNp mpd3-cvs.orig/src/pptp.c mpd3-cvs/src/pptp.c --- mpd3-cvs.orig/src/pptp.c Mon Oct 18 16:49:30 2004 +++ mpd3-cvs/src/pptp.c Tue May 23 22:56:53 2006 @@ -248,6 +248,16 @@ PptpOpen(PhysInfo p) (*pptp->cinfo.answer)(pptp->cinfo.cookie, PPTP_OCR_RESL_OK, 0, 0, 64000 /*XXX*/ ); + + if (pptp->state == PPTP_STATE_DOWN) { + /* XXX Control connection was closed in state OPENING */ + Log(LG_ERR, + ("[%s] Control connection was closed while answering", + lnk->name)); + PptpKillNode(pptp); + break; + } + pptp->state = PPTP_STATE_UP; PhysUp(); return; diff -urNp mpd3-cvs.orig/src/pptp_ctrl.c mpd3-cvs/src/pptp_ctrl.c --- mpd3-cvs.orig/src/pptp_ctrl.c Sun Jul 25 00:25:28 2004 +++ mpd3-cvs/src/pptp_ctrl.c Thu May 25 08:10:11 2006 @@ -838,7 +838,7 @@ abort: c->csock, DEV_PRIO, PptpCtrlReadCtrl, c); /* Start echo keep-alive timer */ - PptpCtrlResetIdleTimer(c); + /* XXX boco PptpCtrlResetIdleTimer(c); */ /* If we originated the call, we start the conversation */ if (c->orig) { @@ -931,7 +931,7 @@ abort: Log(LG_PPTP2, ("pptp%d: recv %s", c->id, gPptpMsgInfo[hdr->type].name)); PptpCtrlDump(LG_PPTP2, hdr->type, msg); c->flen = 0; - PptpCtrlResetIdleTimer(c); + /* XXX boco PptpCtrlResetIdleTimer(c); */ PptpCtrlMsg(c, hdr->type, msg); } } @@ -1100,6 +1100,7 @@ PptpCtrlGetCtrl(int orig, struct in_addr int k; /* See if we're already have a control block matching this address and port */ +/* XXX boco for (k = 0; k < gNumPptpCtrl; k++) { PptpCtrl const c = gPptpCtrl[k]; @@ -1115,6 +1116,7 @@ PptpCtrlGetCtrl(int orig, struct in_addr } } } +XXX boco */ /* Find/create a free one */ for (k = 0; k < gNumPptpCtrl && gPptpCtrl[k] != NULL; k++); @@ -1296,7 +1298,7 @@ PptpCtrlKillCtrl(PptpCtrl c) } EventUnRegister(&c->connEvent); EventUnRegister(&c->ctrlEvent); - TimerStop(&c->idleTimer); + /* XXX boco TimerStop(&c->idleTimer); */ for (prep = c->reps; prep; prep = next) { next = prep->next; TimerStop(&prep->timer); @@ -1375,6 +1377,9 @@ pnsClear: return; case PPTP_CHAN_ST_WAIT_CTRL: PptpCtrlKillChan(ch, "link layer shutdown"); + return; + case PPTP_CHAN_ST_FREE: + Log(LG_PPTP, ("pptp%d-%d: PptpCtrlCloseChan() is called recursively, ignoring", c->id, ch->id)); return; default: assert(0); diff -urNp mpd3-cvs.orig/src/radius.c mpd3-cvs/src/radius.c --- mpd3-cvs.orig/src/radius.c Mon Oct 18 16:49:30 2004 +++ mpd3-cvs/src/radius.c Tue May 23 22:56:53 2006 @@ -31,7 +31,6 @@ static int rad_demangle2(struct rad_handle *, const void *, size_t, u_char *); static int rad_demangle_mppe_key2(struct rad_handle *, const void *, size_t, u_char *, size_t *); - /* Set menu options */ enum { @@ -40,7 +39,9 @@ SET_TIMEOUT, SET_RETRIES, SET_CONFIG, - SET_UPDATE + SET_UPDATE, + SET_UPDATE_LIMIT_IN, + SET_UPDATE_LIMIT_OUT }; /* @@ -60,6 +61,10 @@ RadiusSetCommand, NULL, (void *) SET_CONFIG }, { "acct-update ", "set update interval", RadiusSetCommand, NULL, (void *) SET_UPDATE }, + { "update-limit-in ", "set update limit (inbound traffic)", + RadiusSetCommand, NULL, (void *) SET_UPDATE_LIMIT_IN }, + { "update-limit-out ", "set update limit (outbound traffic)", + RadiusSetCommand, NULL, (void *) SET_UPDATE_LIMIT_OUT }, { NULL }, }; @@ -161,6 +166,22 @@ RadiusSetCommand(int ac, char *av[], voi conf->acct_update = val; break; + case SET_UPDATE_LIMIT_IN: + val = atoi(*av); + if (val <= 0) + Log(LG_ERR, ("Update limit (in) must be positive.")); + else + conf->update_limit_in = val; + break; + + case SET_UPDATE_LIMIT_OUT: + val = atoi(*av); + if (val <= 0) + Log(LG_ERR, ("Update limit (out) must be positive.")); + else + conf->update_limit_out = val; + break; + case SET_RETRIES: val = atoi(*av); if (val <= 0) @@ -757,7 +778,7 @@ RadiusPAPAuthenticate(const char *name, if (RadiusStart(RAD_ACCESS_REQUEST) == RAD_NACK) return RAD_NACK; - if (RadiusPutAuth(name, password, 0, NULL, NULL, 0, RADIUS_PAP) == RAD_NACK) + if (RadiusPutAuth(name, password, 0, NULL, 0, 0, RADIUS_PAP) == RAD_NACK) return RAD_NACK; if (RadiusSendRequest() == RAD_NACK) @@ -1189,6 +1210,7 @@ RadiusAccount(short acct_type) char function[] = "RadiusAccount"; struct radius *rad = &bund->radius; int authentic; + int send_update = 0; /* Should we send acct-update? */ /* if Radius-Auth wasn't used, then copy in authname */ if (!strlen(rad->authname)) @@ -1313,10 +1335,43 @@ RadiusAccount(short acct_type) } } + Log(LG_ALWAYS, ("[%s] ACCT: User-Name=%s NAS-IP-Address=%s NAS-Port=%d " + "Acct-Status-Type=%d Acct-Session-Id=%s Acct-Input-Octets=%u " + "Acct-Output-Octets=%u Acct-Input-Gigawords=%u Acct-Output-Gigawords=%u", + lnk->name, lnk->peer_authname, inet_ntoa(rad->conf.radius_me), + GetLinkID(), acct_type, lnk->radius.session_id, + (unsigned int) (lnk->stats.recvOctets % MAX_U_INT32), + (unsigned int) (lnk->stats.xmitOctets % MAX_U_INT32), + (unsigned int) (lnk->stats.recvOctets / MAX_U_INT32), + (unsigned int) (lnk->stats.xmitOctets / MAX_U_INT32))); + + if (!(rad->conf.update_limit_in || rad->conf.update_limit_out)) + send_update++; + else { + if (rad->conf.update_limit_in && + lnk->stats.recvOctets - lnk->stats.sv_recvOctets > rad->conf.update_limit_in) + send_update++; + if (rad->conf.update_limit_out && + lnk->stats.xmitOctets - lnk->stats.sv_xmitOctets > rad->conf.update_limit_out) + send_update++; + } + + if (acct_type == RAD_UPDATE && !send_update) { + Log(LG_RADIUS, ("[%s] RADIUS: %s: shouldn't send Interim-Update", + lnk->name, function)); + RadiusClose(); + return RAD_NACK; + } + Log(LG_RADIUS, ("[%s] RADIUS: %s: Sending accounting data (Type: %d)", lnk->name, function, acct_type)); if (RadiusSendRequest() == RAD_NACK) return RAD_NACK; + + /* save old statistics (update-limit feature) */ + + lnk->stats.sv_recvOctets = lnk->stats.recvOctets; + lnk->stats.sv_xmitOctets = lnk->stats.xmitOctets; return RAD_ACK; @@ -1417,6 +1472,8 @@ RadStat(int ac, char *av[], void *arg) printf("\tConfig-file : %s\n", conf->file); printf("\tMe (NAS-IP) : %s\n", inet_ntoa(conf->radius_me)); printf("\tAcct-Interval: %d\n", conf->acct_update); + printf("\tUpdate-Limit-In : %d\n", conf->update_limit_in); + printf("\tUpdate-Limit-Out: %d\n", conf->update_limit_out); if (conf->server != NULL) { diff -urNp mpd3-cvs.orig/src/radius.h mpd3-cvs/src/radius.h --- mpd3-cvs.orig/src/radius.h Sat Dec 6 23:50:48 2003 +++ mpd3-cvs/src/radius.h Tue May 23 22:56:53 2006 @@ -101,6 +101,10 @@ extern const struct cmdtab RadiusSetCmds int radius_timeout; int radius_retries; int acct_update; /* Accounting Update Interval */ + int update_limit_in; /* Send Update only when counters + grow more than "update_limit_xx" + since last update */ + int update_limit_out; struct in_addr radius_me; char file[PATH_MAX]; struct radiusserver_conf *server;