Hay We' ve been using mpd3.18 more then half a year and made a few pathces wich fix problems or add some functions to the mpd
1.Patch-aa adds some features: show users command for terminal, fixes ms-chap problems for MS Windows clients, some netgraph fixes. 2. Patch-bb - fixes problem when using Radius authorization. The problem is when radius responces are slow and there are few hundrend users online,due to blocking mpd 3 nature, it spends too much time on waitng for radius responces, not sending and not recieving LCP echo requests, causing timeouts. This comes to mass clients disconnection. Fix makes internal timer which is started for a 2 seconds after first "No valid radius responces recieved" event. This of course make clinet logins inavailable and accounting being sent on blockage time is lost, but the time is pretty small and anyway there are probably problems with the radius so, it's ok, other user's connections stay alive. 3.Patch-gg fixes type for channel id for pptp connection. Even if according to RFC channel id is 8bit long, in mpd it is used to address closing pptp handle in pptp handles array, so after 256 users this causes memory leaks and mpd is likely to got segv on high user traffic (i mean a number of logins/logouts at i time) All patches are in the attachment. There also some other things, like adding CallerId attribute handling for PPTP,PPOE,PPP dial users coming from portservers. And then passing this to radius to have lower level user adresses when doung auth. If someone intrested, let me know. Regards Mikhail Makurov JSC "Intersvyaz", Russia, Chelyabinsk
diff -Nru ./src.orig/chap.c src/chap.c --- ./src.orig/chap.c Tue May 4 22:12:28 2004 +++ src/chap.c Tue Jan 17 15:51:45 2006 @@ -113,6 +113,7 @@ { u_char *pkt; + if (!chap->chal_len) { /* Put random challenge data in buffer (only once for Microsoft CHAP) */ switch (chap->recv_alg) { case CHAP_ALG_MSOFT: { @@ -138,6 +139,7 @@ assert(0); } assert(chap->chal_len <= sizeof(chap->chal_data)); + } /* Build a challenge packet */ pkt = Malloc(MB_AUTH, 1 + chap->chal_len + strlen(bund->conf.authname) + 1); @@ -147,7 +149,7 @@ bund->conf.authname, strlen(bund->conf.authname)); /* Send it off */ - ChapOutput(CHAP_CHALLENGE, chap->next_id++, + ChapOutput(CHAP_CHALLENGE, chap->next_id, pkt, 1 + chap->chal_len + strlen(bund->conf.authname)); Freee(pkt); } @@ -275,7 +277,7 @@ int len, chap_value_size, hash_value_size; /* Sanity check */ - if (lnk->lcp.phase != PHASE_AUTHENTICATE && lnk->lcp.phase != PHASE_NETWORK) { + if (lnk->lcp.phase != PHASE_AUTHENTICATE) { Log(LG_AUTH, ("[%s] CHAP: rec'd stray packet", lnk->name)); PFREE(bp); return; diff -Nru ./src.orig/command.c src/command.c --- ./src.orig/command.c Tue May 4 22:12:28 2004 +++ src/command.c Tue Jan 17 15:40:43 2006 @@ -44,6 +44,7 @@ */ /* Commands */ + static int ShowConnects(int ac, char *av[], void *arg); // ÐÒÏÓÍÏÔÒ ÁËÔÉ×ÎÙÈ ÓÏÅÄÉÎÅÎÉÊ static int ShowVersion(int ac, char *av[], void *arg); static int ShowLayers(int ac, char *av[], void *arg); static int ShowTypes(int ac, char *av[], void *arg); @@ -101,6 +102,8 @@ ShowTypes, NULL, NULL }, { "version", "Version string", ShowVersion, NULL, NULL }, + { "connects", "Show current connections", + ShowConnects, NULL, NULL }, { NULL }, }; @@ -390,6 +393,43 @@ ShowVersion(int ac, char *av[], void *arg) { printf("MPD version: %s\n", gVersion); + return(0); +} + +/* + * ÐÒÏÓÍÏÔÒ ÁËÔÉ×ÎÙÈ ÓÏÅÄÉÎÅÎÉÊ + */ + +static int +ShowConnects(int ac, char *av[], void *arg) +{ + struct bundle const *bund; + struct radius *rad; + int c,cnt; + + printf ("Total bundles count = %d\n",gNumBundles); + printf ("BUNDLE AUTHNAME TYPE IFNAME IP CALLINGID TIME\n"); + for (c = 0, cnt = 0; c < gNumBundles; c++) { + if ((bund = gBundles[c]) != NULL) { + if (bund->open){ + cnt++; + rad=&bund->radius; + printf ("%-8s %-18s %-6s %-7s", + bund->name, + bund->links[0]->peer_authname[0] == '\0' ? "-" : bund->links[0]->peer_authname, + bund->links[0]->phys->type->name, + bund->iface.ifname + ); + printf ("%-15s %-20s %u\n", + inet_ntoa(bund->iface.peer_addr), + rad->calling_id == NULL ? "UNKNOWN" : rad->calling_id, + bund->links[0]->bm.last_open + ); + } + } + } + if (!cnt) + printf (" No active connections\n"); return(0); } diff -Nru ./src.orig/iface.c src/iface.c --- ./src.orig/iface.c Tue May 4 22:12:28 2004 +++ src/iface.c Fri Nov 11 15:27:45 2005 @@ -680,10 +680,11 @@ ns2buf[0] = '\0'; snprintf(peerbuf, sizeof(peerbuf), "%s", inet_ntoa(iface->peer_addr)); - ExecCmd(LG_IFACE, "%s %s inet %s %s %s %s %s", + ExecCmd(LG_IFACE, "%s %s inet %s %s %s %s %s %s", /* ÄÏÐÏÌÎÉÔÅÌØÎÙÊ ×Ù×ÏÄ filter_id × ÓËÒÉÐÔ */ iface->up_script, iface->ifname, inet_ntoa(iface->self_addr), peerbuf, *bund->peer_authname ? bund->peer_authname : bund->conf.authname, + bund->radius.filterid[0] == '\0' ? "NULL" : bund->radius.filterid, ns1buf, ns2buf); } diff -Nru ./src.orig/lcp.c src/lcp.c --- ./src.orig/lcp.c Tue May 4 22:12:28 2004 +++ src/lcp.c Mon Apr 18 02:13:21 2005 @@ -564,8 +564,10 @@ if (!LCP_PEER_REJECTED(lcp, TY_ACCMAP)) cp = FsmConfValue(cp, TY_ACCMAP, -4, &lcp->want_accmap); } + /* úÁËÏÍÅÎÔÉÒÏ×ÁÎÏ ÉÚ ÚÁ ÐÒÏÂÌÅÍ Ó MRU negotiation × RASPPPOE if (!LCP_PEER_REJECTED(lcp, TY_MRU)) cp = FsmConfValue(cp, TY_MRU, -2, &lcp->want_mru); + */ if (lcp->want_magic && !LCP_PEER_REJECTED(lcp, TY_MAGICNUM)) cp = FsmConfValue(cp, TY_MAGICNUM, -4, &lcp->want_magic); if (lcp->want_callback && !LCP_PEER_REJECTED(lcp, TY_CALLBACK)) { diff -Nru ./src.orig/main.c src/main.c --- ./src.orig/main.c Tue May 4 22:12:28 2004 +++ src/main.c Mon Apr 18 01:42:55 2005 @@ -64,6 +64,8 @@ "Show version information" }, { 0, 'h', "help", "", "Show usage information" }, + { 0, 't', "tee", "", + "Insert ng_tee into netgraph" }, }; #define OPTLIST_SIZE (sizeof(OptList) / sizeof(*OptList)) @@ -81,6 +83,7 @@ Bund *gBundles; int gNumLinks; int gNumBundles; + int gEnableTee = FALSE; const char *gConfigFile = CONF_FILE; const char *gConfDirectory = PATH_CONF_DIR; @@ -503,6 +506,9 @@ return(1); case 'k': gKillProc = TRUE; + return(0); + case 't': + gEnableTee = TRUE; return(0); #ifdef SYSLOG_FACILITY case 's': diff -Nru ./src.orig/ngfunc.c src/ngfunc.c --- ./src.orig/ngfunc.c Tue May 4 22:12:28 2004 +++ src/ngfunc.c Wed Nov 9 23:43:29 2005 @@ -28,6 +28,7 @@ #include <netgraph/ng_ppp.h> #include <netgraph/ng_vjc.h> #include <netgraph/ng_bpf.h> +#include <netgraph/ng_tee.h> /* * DEFINITIONS @@ -249,15 +250,39 @@ goto fail; } - /* Connect the other side of the bpf node to the iface node */ - snprintf(path, sizeof(path), "%s.%s", MPD_HOOK_PPP, NG_PPP_HOOK_INET); - 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); + /* Add a tee node between bpf and interface if configured */ + if (gEnableTee) { + snprintf(path, sizeof(path), "%s.%s", MPD_HOOK_PPP, NG_PPP_HOOK_INET); + snprintf(mp.type, sizeof(mp.type), "%s", NG_TEE_NODE_TYPE); + snprintf(mp.ourhook, sizeof(mp.ourhook), "%s", BPF_HOOK_IFACE); + snprintf(mp.peerhook, sizeof(mp.peerhook), "%s", NG_TEE_HOOK_RIGHT); + 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_TEE_NODE_TYPE, strerror(errno))); + goto fail; + } + + snprintf(path, sizeof(path), "%s.%s.%s", MPD_HOOK_PPP, NG_PPP_HOOK_INET, + BPF_HOOK_IFACE); + snprintf(cn.path, sizeof(cn.path), "%s:", b->iface.ifname); + snprintf(cn.ourhook, sizeof(cn.ourhook), "%s", NG_TEE_HOOK_LEFT); + snprintf(cn.peerhook, sizeof(cn.peerhook), "%s", NG_IFACE_HOOK_INET); + + } else { + + /* Connect the other side of the bpf node to the iface node */ + snprintf(path, sizeof(path), "%s.%s", MPD_HOOK_PPP, NG_PPP_HOOK_INET); + 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); + + } + if (NgSendMsg(b->csock, path, NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) { Log(LG_ERR, ("[%s] can't connect %s and %s: %s", - b->name, BPF_HOOK_IFACE, NG_IFACE_HOOK_INET, strerror(errno))); + b->name, cn.ourhook, NG_IFACE_HOOK_INET, strerror(errno))); goto fail; } @@ -473,7 +498,11 @@ char path[NG_PATHLEN + 1]; /* Get absolute path to bpf node */ - snprintf(path, sizeof(path), "%s:%s", b->iface.ifname, NG_IFACE_HOOK_INET); + 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)); diff -Nru ./src.orig/ppp.h src/ppp.h --- ./src.orig/ppp.h Tue May 4 22:12:28 2004 +++ src/ppp.h Wed Sep 14 11:46:22 2005 @@ -12,7 +12,8 @@ /* Increase this if you have zillions of bundles */ -#define FD_SETSIZE 8192 +//#define FD_SETSIZE 8192 +#define FD_SETSIZE 65536 /* Keep source files simple */ @@ -84,6 +85,7 @@ extern int gNumLinks; /* Total number of links */ extern int gNumBundles; /* Total number of bundles */ + extern int gEnableTee; /* Insert ng_tee into netgraph */ extern Bund bund; /* Current bundle */ extern Link lnk; /* Current link */ diff -Nru ./src.orig/pptp.c src/pptp.c --- ./src.orig/pptp.c Tue May 4 22:12:28 2004 +++ src/pptp.c Fri Nov 11 14:17:51 2005 @@ -241,6 +241,16 @@ (*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 -Nru ./src.orig/pptp_ctrl.c src/pptp_ctrl.c --- ./src.orig/pptp_ctrl.c Tue May 4 22:12:28 2004 +++ src/pptp_ctrl.c Fri Nov 11 12:11:49 2005 @@ -1373,6 +1373,9 @@ 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 -Nru ./src.orig/radius.c src/radius.c --- ./src.orig/radius.c Tue May 4 22:12:28 2004 +++ src/radius.c Fri Nov 11 15:39:58 2005 @@ -359,6 +359,7 @@ peer_ip = PptpGetPeerIp(); if (peer_ip != NULL && peer_ip->s_addr != 0) { peeripname = inet_ntoa(*peer_ip); + rad->calling_id=strdup(peeripname); if (peeripname != NULL) { if (rad_put_string(rad->radh, RAD_CALLING_STATION_ID, peeripname) == -1) { Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_put_string(RAD_CALLING_STATION_ID) failed %s", lnk->name, @@ -369,13 +370,15 @@ } } + peer_mac = PppoeGetPeerAddr(); if ((peer_mac != NULL) && ((peer_mac[0] != 0) || (peer_mac[1] != 0) || (peer_mac[2] != 0) || (peer_mac[3] !=0 ) || (peer_mac[4] != 0) || (peer_mac[5] != 0)) ) { - snprintf(peermacname, sizeof(peermacname), "%02x%02x%02x%02x%02x%02x", + snprintf(peermacname, sizeof(peermacname), "%02x:%02x:%02x:%02x:%02x:%02x", peer_mac[0], peer_mac[1], peer_mac[2], peer_mac[3], peer_mac[4], peer_mac[5]); + rad->calling_id=strdup(peermacname); if (rad_put_string(rad->radh, RAD_CALLING_STATION_ID, peermacname) == -1) { Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_put_string(RAD_CALLING_STATION_ID) failed %s", lnk->name, function, rad_strerror(rad->radh))); @@ -383,7 +386,7 @@ return (RAD_NACK); } } - + return RAD_ACK; } @@ -800,7 +803,7 @@ size_t len; const void *data; u_int32_t vendor; - char *route; + char *route, *filterid; char *acl1,*acl2; struct radius_acl **acls, *acls1; struct ifaceroute r; @@ -817,6 +820,21 @@ lnk->name, function, inet_ntoa(rad->ip))); break; + case RAD_FILTER_ID: + filterid = rad_cvt_string(data,len); + Log(LG_RADIUS, ("[%s] RADIUS: %s: RAD_FILTER_ID: %s ", + lnk->name, function, filterid)); + + if ( rad->filterid[0] == '\0' ) + { + strncpy(rad->filterid,filterid,RAD_MAX_FILTER_ID); + } else + { + snprintf(rad->filterid,RAD_MAX_FILTER_ID,"%s,%s",rad->filterid,filterid); + } + free(filterid); + break; + case RAD_FRAMED_IP_NETMASK: rad->mask = rad_cvt_addr(data); Log(LG_RADIUS, ("[%s] RADIUS: %s: RAD_FRAMED_IP_NETMASK: %s ", @@ -1394,6 +1412,7 @@ printf("\tProtocol : %lu\n", rad->protocol); printf("\tService-type : %lu\n", rad->service_type); printf("\tFilter-Id : %s\n", rad->filterid == NULL ? "" : rad->filterid); + printf("\tCalling-Id : %s\n", rad->calling_id == NULL ? "" : rad->calling_id); printf("\tAcct-SID : %s\n", lnk->radius.session_id); printf("\tAcct-MSID : %s\n", rad->multi_session_id); diff -Nru ./src.orig/radius.h src/radius.h --- ./src.orig/radius.h Tue May 4 22:12:28 2004 +++ src/radius.h Fri Nov 11 15:15:22 2005 @@ -53,6 +53,8 @@ /* max. length of RAD_ACCT_SESSION_ID, RAD_ACCT_MULTI_SESSION_ID */ #define RAD_ACCT_MAX_SESSIONID 256 +#define RAD_MAX_FILTER_ID 256 + /* max. length of acl rule, */ #define ACL_LEN 256 @@ -135,7 +137,8 @@ unsigned long protocol; /* FRAMED Protocol */ unsigned long service_type; /* Service Type */ unsigned long interim_interval; /* interval for accouting updates */ - char *filterid; /* FRAMED Filter Id */ + char filterid[RAD_MAX_FILTER_ID]; /* FRAMED Filter Id */ + char *calling_id; /* Calling-Station-Id */ char *msdomain; /* Microsoft domain */ char *mschap_error; /* MSCHAP Error Message */ char *mschapv2resp; /* Response String for MSCHAPv2 */
diff -u src.orig/main.c src/main.c --- src.orig/main.c Thu Jun 29 10:14:48 2006 +++ src/main.c Thu Jun 29 10:19:08 2006 @@ -84,6 +84,8 @@ int gNumLinks; int gNumBundles; int gEnableTee = FALSE; + int RadiusBlocked; + struct timeval RadiusBlockTime; const char *gConfigFile = CONF_FILE; const char *gConfDirectory = PATH_CONF_DIR; @@ -134,6 +136,7 @@ int console_fd; char *args[MAX_ARGS]; + RadiusBlocked=0; /* Read and parse command line */ if (ac > MAX_ARGS) ac = MAX_ARGS; diff -u src.orig/radius.c src/radius.c --- src.orig/radius.c Thu Jun 29 10:14:48 2006 +++ src/radius.c Thu Jun 29 10:23:24 2006 @@ -17,6 +17,9 @@ #include <radlib_vs.h> #include <md5.h> +//time for which to block radius operations, in seconds +#define RAD_BLOCK_TIME 2 + /* Global variables */ static int RadiusSetCommand(int ac, char *av[], void *arg); @@ -29,6 +32,8 @@ 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 *); + extern int RadiusBlocked; + extern struct timeval RadiusBlockTime; /* Set menu options */ @@ -610,6 +615,20 @@ struct timeval tv; int fd, n; + gettimeofday(&timelimit, NULL); + + if (RadiusBlocked ) { + if ( ( (RadiusBlockTime.tv_sec+RAD_BLOCK_TIME) - timelimit.tv_sec)>0) { + Log(LG_RADIUS, ("[%s] RADIUS: %s: Sending request failed, radius is blocked %d seconds left...", lnk->name, function, + (RadiusBlockTime.tv_sec+RAD_BLOCK_TIME)- timelimit.tv_sec )); + //destroing curent request - it is discarded + RadiusDestroy(); + return RAD_NACK; + } + Log(LG_RADIUS, ("[%s] RADIUS: %s: Unblock timeout, Unblocking radius ...", lnk->name, function)); + RadiusBlocked=0; + } + #ifdef DEBUG Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_init_send_request ...", lnk->name, function)); #endif @@ -679,9 +698,14 @@ return RAD_ACK; case -1: - Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_send_request failed %s", lnk->name, + Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_send_request failed %s, blocking RADIUS operations %s", lnk->name, function, rad_strerror(rad->radh))); RadiusClose(); + + //setting a radius blocking flag and filling blocked time struct + gettimeofday(&RadiusBlockTime, NULL); + RadiusBlocked=1; + return(RAD_NACK); break;
diff -rNu src/pptp_ctrl.c src.new/pptp_ctrl.c --- src/pptp_ctrl.c Thu Jun 22 13:45:03 2006 +++ src.new/pptp_ctrl.c Thu Jun 22 13:46:05 2006 @@ -127,7 +127,7 @@ /* Control channel state */ struct pptpctrl { u_char state; /* state */ - u_char id; /* channel index */ + u_int32_t id; /* channel index */ u_char orig:1; /* we originated connection */ u_char killing:1; /* connection is being killed */ union {
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________ Mpd-users mailing list Mpd-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mpd-users