From owner-p4-projects@FreeBSD.ORG Mon Oct 30 17:49:37 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6FA4D16A49E; Mon, 30 Oct 2006 17:49:37 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1D86116A47E for ; Mon, 30 Oct 2006 17:49:37 +0000 (UTC) (envelope-from piso@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id D976D43D58 for ; Mon, 30 Oct 2006 17:49:36 +0000 (GMT) (envelope-from piso@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k9UHnaDE091123 for ; Mon, 30 Oct 2006 17:49:36 GMT (envelope-from piso@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k9UHna9Y091119 for perforce@freebsd.org; Mon, 30 Oct 2006 17:49:36 GMT (envelope-from piso@freebsd.org) Date: Mon, 30 Oct 2006 17:49:36 GMT Message-Id: <200610301749.k9UHna9Y091119@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to piso@freebsd.org using -f From: Paolo Pisati To: Perforce Change Reviews Cc: Subject: PERFORCE change 108766 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Oct 2006 17:49:37 -0000 http://perforce.freebsd.org/chv.cgi?CH=108766 Change 108766 by piso@piso_newluxor on 2006/10/30 17:49:03 Libalias locking: embed a sleep mtx per struct libalias instance, and grab/drop it at the entrance/exit of every public LibAlias* function. Not tested yet... Affected files ... .. //depot/projects/soc2005/libalias/sys/netinet/libalias/alias.c#19 edit .. //depot/projects/soc2005/libalias/sys/netinet/libalias/alias_db.c#13 edit .. //depot/projects/soc2005/libalias/sys/netinet/libalias/alias_local.h#8 edit .. //depot/projects/soc2005/libalias/sys/netinet/libalias/alias_proxy.c#9 edit .. //depot/projects/soc2005/libalias/sys/netinet/libalias/alias_util.c#4 edit Differences ... ==== //depot/projects/soc2005/libalias/sys/netinet/libalias/alias.c#19 (text+ko) ==== @@ -1138,6 +1138,7 @@ struct alias_link *lnk; struct ip *pip; + LIBALIAS_LOCK(la); pip = (struct ip *)ptr; lnk = AddFragmentPtrLink(la, pip->ip_src, pip->ip_id); iresult = PKT_ALIAS_ERROR; @@ -1145,6 +1146,7 @@ SetFragmentPtr(lnk, ptr); iresult = PKT_ALIAS_OK; } + LIBALIAS_UNLOCK(la); return (iresult); } @@ -1156,17 +1158,18 @@ char *fptr; struct ip *pip; + LIBALIAS_LOCK(la); pip = (struct ip *)ptr; lnk = FindFragmentPtr(la, pip->ip_src, pip->ip_id); if (lnk != NULL) { GetFragmentPtr(lnk, &fptr); SetFragmentPtr(lnk, NULL); SetExpire(lnk, 0); /* Deletes link */ + } else + fptr = NULL; - return (fptr); - } else { - return (NULL); - } + LIBALIAS_UNLOCK(la); + return (fptr); } @@ -1181,6 +1184,7 @@ struct ip *pip; struct ip *fpip; + LIBALIAS_LOCK(la); (void)la; pip = (struct ip *)ptr; fpip = (struct ip *)ptr_fragment; @@ -1188,6 +1192,7 @@ DifferentialChecksum(&fpip->ip_sum, &pip->ip_dst, &fpip->ip_dst, 2); fpip->ip_dst = pip->ip_dst; + LIBALIAS_UNLOCK(la); } @@ -1198,11 +1203,12 @@ struct ip *pip; int iresult; + LIBALIAS_LOCK(la); if (la->packetAliasMode & PKT_ALIAS_REVERSE) { la->packetAliasMode &= ~PKT_ALIAS_REVERSE; iresult = LibAliasOut(la, ptr, maxpacketsize); la->packetAliasMode |= PKT_ALIAS_REVERSE; - return (iresult); + goto getout; } HouseKeeping(la); ClearCheckNewLink(la); @@ -1211,8 +1217,10 @@ /* Defense against mangled packets */ if (ntohs(pip->ip_len) > maxpacketsize - || (pip->ip_hl << 2) > maxpacketsize) - return (PKT_ALIAS_IGNORED); + || (pip->ip_hl << 2) > maxpacketsize) { + iresult = PKT_ALIAS_IGNORED; + goto getout; + } iresult = PKT_ALIAS_IGNORED; if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) { @@ -1266,6 +1274,8 @@ iresult = FragmentIn(la, pip); } +getout: + LIBALIAS_UNLOCK(la); return (iresult); } @@ -1305,11 +1315,12 @@ struct in_addr addr_save; struct ip *pip; + LIBALIAS_LOCK(la); if (la->packetAliasMode & PKT_ALIAS_REVERSE) { la->packetAliasMode &= ~PKT_ALIAS_REVERSE; iresult = LibAliasIn(la, ptr, maxpacketsize); la->packetAliasMode |= PKT_ALIAS_REVERSE; - return (iresult); + goto getout; } HouseKeeping(la); ClearCheckNewLink(la); @@ -1317,8 +1328,10 @@ /* Defense against mangled packets */ if (ntohs(pip->ip_len) > maxpacketsize - || (pip->ip_hl << 2) > maxpacketsize) - return (PKT_ALIAS_IGNORED); + || (pip->ip_hl << 2) > maxpacketsize) { + iresult = PKT_ALIAS_IGNORED; + goto getout; + } addr_save = GetDefaultAliasAddress(la); if (la->packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY) { @@ -1380,6 +1393,8 @@ } SetDefaultAliasAddress(la, addr_save); +getout: + LIBALIAS_UNLOCK(la); return (iresult); } @@ -1395,12 +1410,13 @@ struct alias_link *lnk; int iresult = PKT_ALIAS_IGNORED; + LIBALIAS_LOCK(la); pip = (struct ip *)ptr; /* Defense against mangled packets */ if (ntohs(pip->ip_len) > maxpacketsize || (pip->ip_hl << 2) > maxpacketsize) - return (iresult); + goto getout; ud = (struct udphdr *)ip_next(pip); tc = (struct tcphdr *)ip_next(pip); @@ -1484,6 +1500,8 @@ iresult = PKT_ALIAS_OK; } } +getout: + LIBALIAS_UNLOCK(la); return (iresult); } ==== //depot/projects/soc2005/libalias/sys/netinet/libalias/alias_db.c#13 (text+ko) ==== @@ -2273,6 +2273,7 @@ int link_type; struct alias_link *lnk; + LIBALIAS_LOCK(la); switch (proto) { case IPPROTO_UDP: link_type = LINK_UDP; @@ -2285,7 +2286,8 @@ fprintf(stderr, "PacketAliasRedirectPort(): "); fprintf(stderr, "only TCP and UDP protocols allowed\n"); #endif - return (NULL); + lnk = NULL; + goto getout; } lnk = AddLink(la, src_addr, dst_addr, alias_addr, @@ -2302,6 +2304,8 @@ } #endif +getout: + LIBALIAS_UNLOCK(la); return (lnk); } @@ -2310,7 +2314,9 @@ LibAliasAddServer(struct libalias *la, struct alias_link *lnk, struct in_addr addr, u_short port) { struct server *server; + int res; + LIBALIAS_LOCK(la); (void)la; server = malloc(sizeof(struct server)); @@ -2332,9 +2338,12 @@ server->next = head; } lnk->server = server; - return (0); + res = 0; } else - return (-1); + res = -1; + + LIBALIAS_UNLOCK(la); + return (res); } /* Redirect packets of a given IP protocol from a specific @@ -2346,7 +2355,8 @@ u_char proto) { struct alias_link *lnk; - + + LIBALIAS_LOCK(la); lnk = AddLink(la, src_addr, dst_addr, alias_addr, NO_SRC_PORT, NO_DEST_PORT, 0, proto); @@ -2361,6 +2371,7 @@ } #endif + LIBALIAS_UNLOCK(la); return (lnk); } @@ -2371,6 +2382,7 @@ { struct alias_link *lnk; + LIBALIAS_LOCK(la); lnk = AddLink(la, src_addr, la->nullAddress, alias_addr, 0, 0, 0, LINK_ADDR); @@ -2385,6 +2397,7 @@ } #endif + LIBALIAS_UNLOCK(la); return (lnk); } @@ -2393,15 +2406,19 @@ int LibAliasRedirectDynamic(struct libalias *la, struct alias_link *lnk) { + int res; + LIBALIAS_LOCK(la); (void)la; if (lnk->flags & LINK_PARTIALLY_SPECIFIED) - return (-1); + res = -1; else { lnk->flags &= ~LINK_PERMANENT; - return (0); + res = 0; } + LIBALIAS_UNLOCK(la); + return (res); } @@ -2411,27 +2428,35 @@ /* This is a dangerous function to put in the API, because an invalid pointer can crash the program. */ + LIBALIAS_LOCK(la); la->deleteAllLinks = 1; DeleteLink(lnk); la->deleteAllLinks = 0; + LIBALIAS_UNLOCK(la); } void LibAliasSetAddress(struct libalias *la, struct in_addr addr) { + + LIBALIAS_LOCK(la); if (la->packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE && la->aliasAddress.s_addr != addr.s_addr) CleanupAliasData(la); la->aliasAddress = addr; + LIBALIAS_UNLOCK(la); } void LibAliasSetTarget(struct libalias *la, struct in_addr target_addr) { + + LIBALIAS_LOCK(la); la->targetAddress = target_addr; + LIBALIAS_UNLOCK(la); } static void @@ -2508,12 +2533,15 @@ #ifndef _KERNEL LibAliasRefreshModules(); #endif + LIBALIAS_LOCK_INIT(la); return (la); } void LibAliasUninit(struct libalias *la) { + + LIBALIAS_LOCK(la); la->deleteAllLinks = 1; CleanupAliasData(la); la->deleteAllLinks = 0; @@ -2522,6 +2550,8 @@ UninitPunchFW(la); #endif LIST_REMOVE(la, instancelist); + LIBALIAS_UNLOCK(la); + LIBALIAS_LOCK_DESTROY(la); free(la); } @@ -2534,11 +2564,15 @@ * do a probe for flag values) */ ) { + + LIBALIAS_LOCK(la); /* Enable logging? */ if (flags & mask & PKT_ALIAS_LOG) { /* Do the enable */ - if (InitPacketAliasLog(la) == ENOMEM) + if (InitPacketAliasLog(la) == ENOMEM) { + LIBALIAS_UNLOCK(la); return (-1); + } } else /* _Disable_ logging? */ if (~flags & mask & PKT_ALIAS_LOG) { @@ -2557,6 +2591,7 @@ /* Other flags can be set/cleared without special action */ la->packetAliasMode = (flags & mask) | (la->packetAliasMode & ~mask); + LIBALIAS_UNLOCK(la); return (la->packetAliasMode); } @@ -2564,7 +2599,12 @@ int LibAliasCheckNewLink(struct libalias *la) { - return (la->newDefaultLink); + int res; + + LIBALIAS_LOCK(la); + res = la->newDefaultLink; + LIBALIAS_UNLOCK(la); + return (res); } @@ -2819,14 +2859,20 @@ void LibAliasSetFWBase(struct libalias *la, unsigned int base, unsigned int num) { + + LIBALIAS_LOCK(la); #ifndef NO_FW_PUNCH la->fireWallBaseNum = base; la->fireWallNumNums = num; #endif + LIBALIAS_UNLOCK(la); } void LibAliasSetSkinnyPort(struct libalias *la, unsigned int port) { + + LIBALIAS_LOCK(la); la->skinnyPort = port; + LIBALIAS_UNLOCK(la); } ==== //depot/projects/soc2005/libalias/sys/netinet/libalias/alias_local.h#8 (text+ko) ==== @@ -51,7 +51,10 @@ #ifdef _KERNEL #include +#include #include +#include + /* XXX: LibAliasSetTarget() uses this constant. */ #define INADDR_NONE 0xffffffff #endif @@ -146,11 +149,29 @@ struct in_addr true_addr; /* in network byte order. */ u_short true_port; /* in host byte order. */ - +#ifdef _KERNEL + /* + * avoid races in libalias: every pubblic function has to use it. + */ + struct mtx mutex; +#endif }; /* Macros */ +#ifdef _KERNEL +#define LIBALIAS_LOCK_INIT(l) \ + mtx_init(&l->mutex, "per-instance libalias mutex", NULL, MTX_DEF|MTX_RECURSE) +#define LIBALIAS_LOCK(l) mtx_lock(&l->mutex) +#define LIBALIAS_UNLOCK(l) mtx_unlock(&l->mutex) +#define LIBALIAS_LOCK_DESTROY(l) mtx_destroy(&l->mutex); +#else +#define LIBALIAS_LOCK_INIT(l) +#define LIBALIAS_LOCK(l) +#define LIBALIAS_UNLOCK(l) +#define LIBALIAS_LOCK_DESTROY(l) +#endif + /* * The following macro is used to update an * internet checksum. "delta" is a 32-bit ==== //depot/projects/soc2005/libalias/sys/netinet/libalias/alias_proxy.c#9 (text+ko) ==== @@ -648,7 +648,7 @@ * then 0 is used, and group 0 rules are always checked before any * others. */ - int i, n, len; + int i, n, len, ret; int cmd_len; int token_count; int state; @@ -668,11 +668,15 @@ struct in_addr dst_addr, dst_mask; struct proxy_entry *proxy_entry; + LIBALIAS_LOCK(la); + ret = 0; /* Copy command line into a buffer */ cmd += strspn(cmd, " \t"); cmd_len = strlen(cmd); - if (cmd_len > (int)(sizeof(buffer) - 1)) - return (-1); + if (cmd_len > (int)(sizeof(buffer) - 1)) { + ret = -1; + goto getout; + } strcpy(buffer, cmd); /* Convert to lower case */ @@ -730,8 +734,10 @@ state = STATE_READ_SRC; else if (strcmp(token, "dst") == 0) state = STATE_READ_DST; - else - return (-1); + else { + ret = -1; + goto getout; + } break; case STATE_READ_TYPE: @@ -741,8 +747,10 @@ proxy_type = PROXY_TYPE_ENCODE_TCPSTREAM; else if (strcmp(token, "no_encode") == 0) proxy_type = PROXY_TYPE_ENCODE_NONE; - else - return (-1); + else { + ret = -1; + goto getout; + } state = STATE_READ_KEYWORD; break; @@ -763,18 +771,24 @@ if (*p != ':') { err = IpAddr(token, &server_addr); - if (err) - return (-1); + if (err) { + ret = -1; + goto getout; + } } else { *p = ' '; n = sscanf(token, "%s %s", s, str_server_port); - if (n != 2) - return (-1); + if (n != 2) { + ret = -1; + goto getout; + } err = IpAddr(s, &server_addr); - if (err) - return (-1); + if (err) { + ret = -1; + goto getout; + } } } state = STATE_READ_KEYWORD; @@ -782,8 +796,10 @@ case STATE_READ_RULE: n = sscanf(token, "%d", &rule_index); - if (n != 1 || rule_index < 0) - return (-1); + if (n != 1 || rule_index < 0) { + ret = -1; + goto getout; + } state = STATE_READ_KEYWORD; break; @@ -792,16 +808,21 @@ int err; int rule_to_delete; - if (token_count != 2) - return (-1); + if (token_count != 2) { + ret = -1; + goto getout; + } n = sscanf(token, "%d", &rule_to_delete); - if (n != 1) - return (-1); + if (n != 1) { + ret = -1; + goto getout; + } err = RuleNumberDelete(la, rule_to_delete); if (err) - return (-1); - return (0); + ret = -1; + ret = 0; + goto getout; } case STATE_READ_PROTO: @@ -809,8 +830,10 @@ proto = IPPROTO_TCP; else if (strcmp(token, "udp") == 0) proto = IPPROTO_UDP; - else - return (-1); + else { + ret = -1; + goto getout; + } state = STATE_READ_KEYWORD; break; @@ -829,24 +852,32 @@ if (*p != '/') { IpMask(32, &mask); err = IpAddr(token, &addr); - if (err) - return (-1); + if (err) { + ret = -1; + goto getout; + } } else { int nbits; char s[sizeof(buffer)]; *p = ' '; n = sscanf(token, "%s %d", s, &nbits); - if (n != 2) - return (-1); + if (n != 2) { + ret = -1; + goto getout; + } err = IpAddr(s, &addr); - if (err) - return (-1); + if (err) { + ret = -1; + goto getout; + } err = IpMask(nbits, &mask); - if (err) - return (-1); + if (err) { + ret = -1; + goto getout; + } } if (state == STATE_READ_SRC) { @@ -861,7 +892,8 @@ break; default: - return (-1); + ret = -1; + goto getout; break; } @@ -887,8 +919,10 @@ int err; err = IpPort(str_port, proto, &proxy_port); - if (err) - return (-1); + if (err) { + ret = -1; + goto getout; + } } else { proxy_port = 0; } @@ -897,20 +931,26 @@ int err; err = IpPort(str_server_port, proto, &server_port); - if (err) - return (-1); + if (err) { + ret = -1; + goto getout; + } } else { server_port = 0; } /* Check that at least the server address has been defined */ - if (server_addr.s_addr == 0) - return (-1); + if (server_addr.s_addr == 0) { + ret = -1; + goto getout; + } /* Add to linked list */ proxy_entry = malloc(sizeof(struct proxy_entry)); - if (proxy_entry == NULL) - return (-1); + if (proxy_entry == NULL) { + ret = -1; + goto getout; + } proxy_entry->proxy_type = proxy_type; proxy_entry->rule_index = rule_index; @@ -925,5 +965,7 @@ RuleAdd(la, proxy_entry); - return (0); +getout: + LIBALIAS_UNLOCK(la); + return (ret); } ==== //depot/projects/soc2005/libalias/sys/netinet/libalias/alias_util.c#4 (text+ko) ==== @@ -76,6 +76,7 @@ { int sum, oddbyte; + LIBALIAS_LOCK(la); sum = 0; while (nbytes > 1) { sum += *ptr++; @@ -89,6 +90,7 @@ } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); + LIBALIAS_UNLOCK(la); return (~sum); }