diff options
author | venaas <venaas> | 2008-07-31 18:02:20 +0000 |
---|---|---|
committer | venaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf> | 2008-07-31 18:02:20 +0000 |
commit | 0abcf37347f020747f5a2b3986782629fb267d2a (patch) | |
tree | 60c4ab320000e7ec334c056a37309e38cbc6fbfd | |
parent | df95c2144732f5323e16d9cf91f55455743a4fa9 (diff) |
added radudpget2 that is to replace radudpget
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@331 e88ac4ed-0b26-0410-9574-a7f39faa03bf
-rw-r--r-- | radsecproxy.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/radsecproxy.c b/radsecproxy.c index 6e341c2..293fafb 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -768,6 +768,85 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, return rad; } +/* exactly one of client and server must be non-NULL */ +/* should probably take peer list (client(s) or server(s)) as argument instead */ +/* if *peer == NULL we return who we received from, else require it to be from peer */ +/* return from in sa if not NULL */ +unsigned char *radudpget2(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) { + int cnt, len; + unsigned char buf[4], *rad; + struct sockaddr_storage from; + socklen_t fromlen = sizeof(from); + struct clsrvconf *p; + struct list_node *node; + + for (;;) { + cnt = recvfrom(s, buf, 4, MSG_PEEK, (struct sockaddr *)&from, &fromlen); + if (cnt == -1) { + debug(DBG_WARN, "radudpget: recv failed"); + continue; + } + + if (client) + if (*client) + p = checkconfaddr(RAD_UDP, (struct sockaddr *)&from, (*client)->conf); + else + p = find_conf(RAD_UDP, (struct sockaddr *)&from, clconfs, NULL); + else + if (*server) + p = checkconfaddr(RAD_UDP, (struct sockaddr *)&from, (*server)->conf); + else + p = find_conf(RAD_UDP, (struct sockaddr *)&from, srvconfs, NULL); + + if (!p) { + debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer %s, ignoring", addr2string((struct sockaddr *)&from, fromlen)); + recv(s, buf, 4, 0); + continue; + } + + len = RADLEN(buf); + if (len < 20) { + debug(DBG_WARN, "radudpget: length too small"); + recv(s, buf, 4, 0); + continue; + } + + rad = malloc(len); + if (!rad) { + debug(DBG_ERR, "radudpget: malloc failed"); + recv(s, buf, 4, 0); + continue; + } + + cnt = recv(s, rad, len, MSG_TRUNC); + debug(DBG_DBG, "radudpget: got %d bytes from %s", cnt, addr2string((struct sockaddr *)&from, fromlen)); + + if (cnt < len) { + debug(DBG_WARN, "radudpget: packet smaller than length field in radius header"); + free(rad); + continue; + } + + if (cnt > len) + debug(DBG_DBG, "radudpget: packet was padded with %d bytes", cnt - len); + + if (client && !*client) { + node = list_first(p->clients); + *client = node ? (struct client *)node->data : addclient(p); + if (!*client) { + free(rad); + continue; + } + } else if (server && !*server) + *server = p->servers; + + break; + } + if (sa) + *sa = from; + return rad; +} + int subjectaltnameaddr(X509 *cert, int family, struct in6_addr *addr) { int loc, i, l, n, r = 0; char *v; |