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

Reply via email to