myipaddr was not thread safe. there are two free-loaders with this patch, a bit of formatting for ip(2), which may need to be redone in a better way, and the expansion of ip statstics to uvlongs to prevent overflows. Notes: Mon Mar 17 18:18:19 EDT 2014 geoff mostly dubious. Reference: /n/sources/patch/maybe/myipaddr-thread Date: Sun Feb 19 14:47:57 CET 2012 Signed-off-by: quanstro@quanstro.net Reviewed-by: geoff --- /sys/src/libip/myipaddr.c Sun Feb 19 14:45:47 2012 +++ /sys/src/libip/myipaddr.c Sun Feb 19 14:45:46 2012 @@ -20,12 +20,11 @@ int myipaddr(uchar *ip, char *net) { - Ipifc *nifc; + Ipifc *nifc, *ifc; Iplifc *lifc; - static Ipifc *ifc; uchar mynet[IPaddrlen]; - ifc = readipifc(net, ifc, -1); + ifc = readipifc(net, nil, -1); for(nifc = ifc; nifc; nifc = nifc->next) for(lifc = nifc->lifc; lifc; lifc = lifc->next){ maskip(lifc->ip, loopbackmask, mynet); @@ -34,9 +33,11 @@ } if(ipcmp(lifc->ip, IPnoaddr) != 0){ ipmove(ip, lifc->ip); + freeipifc(ifc); return 0; } } ipmove(ip, IPnoaddr); + freeipifc(ifc); return -1; } --- /sys/src/libip/readipifc.c Sun Feb 19 14:45:50 2012 +++ /sys/src/libip/readipifc.c Sun Feb 19 14:45:48 2012 @@ -3,46 +3,6 @@ #include #include -static Ipifc** -_readoldipifc(char *buf, Ipifc **l, int index) -{ - char *f[200]; - int i, n; - Ipifc *ifc; - Iplifc *lifc, **ll; - - /* allocate new interface */ - *l = ifc = mallocz(sizeof(Ipifc), 1); - if(ifc == nil) - return l; - l = &ifc->next; - ifc->index = index; - - n = tokenize(buf, f, nelem(f)); - if(n < 2) - return l; - - strncpy(ifc->dev, f[0], sizeof ifc->dev); - ifc->dev[sizeof(ifc->dev) - 1] = 0; - ifc->mtu = strtoul(f[1], nil, 10); - - ll = &ifc->lifc; - for(i = 2; n-i >= 7; i += 7){ - /* allocate new local address */ - *ll = lifc = mallocz(sizeof(Iplifc), 1); - ll = &lifc->next; - - parseip(lifc->ip, f[i]); - parseipmask(lifc->mask, f[i+1]); - parseip(lifc->net, f[i+2]); - ifc->pktin = strtoul(f[i+3], nil, 10); - ifc->pktout = strtoul(f[i+4], nil, 10); - ifc->errin = strtoul(f[i+5], nil, 10); - ifc->errout = strtoul(f[i+6], nil, 10); - } - return l; -} - static char* findfield(char *name, char **f, int n) { @@ -74,8 +34,6 @@ buf[n] = 0; close(fd); - if(strncmp(buf, "device", 6) != 0) - return _readoldipifc(buf, l, index); /* ignore ifcs with no associated device */ if(strncmp(buf+6, " ", 2) == 0) return l; @@ -113,10 +71,10 @@ ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n)); ifc->rp.ttl = atoi(findfield("ttl", f, n)); ifc->rp.routerlt = atoi(findfield("routerlt", f, n)); - ifc->pktin = strtoul(findfield("pktin", f, n), nil, 10); - ifc->pktout = strtoul(findfield("pktout", f, n), nil, 10); - ifc->errin = strtoul(findfield("errin", f, n), nil, 10); - ifc->errout = strtoul(findfield("errout", f, n), nil, 10); + ifc->pktin = strtoull(findfield("pktin", f, n), nil, 10); + ifc->pktout = strtoull(findfield("pktout", f, n), nil, 10); + ifc->errin = strtoull(findfield("errin", f, n), nil, 10); + ifc->errout = strtoull(findfield("errout", f, n), nil, 10); /* now read the addresses */ ll = &ifc->lifc; @@ -140,14 +98,12 @@ return l; } -static void -_freeifc(Ipifc *ifc) +void +freeipifc(Ipifc *ifc) { Ipifc *next; Iplifc *lnext, *lifc; - if(ifc == nil) - return; for(; ifc; ifc = next){ next = ifc->next; for(lifc = ifc->lifc; lifc; lifc = lnext){ @@ -167,7 +123,7 @@ char buf[128]; Ipifc **l; - _freeifc(ifc); + freeipifc(ifc); l = &ifc; ifc = nil; --- /sys/include/ip.h Sun Feb 19 14:45:52 2012 +++ /sys/include/ip.h Sun Feb 19 14:45:51 2012 @@ -60,10 +60,10 @@ uchar sendra6; /* on == send router adv */ uchar recvra6; /* on == rcv router adv */ int mtu; - ulong pktin; - ulong pktout; - ulong errin; - ulong errout; + uvlong pktin; + uvlong pktout; + uvlong errin; + uvlong errout; Ipv6rp rp; }; @@ -170,6 +170,7 @@ int equivip4(uchar*, uchar*); int equivip6(uchar*, uchar*); +void freeipifc(Ipifc*); Ipifc* readipifc(char*, Ipifc*, int); void hnputv(void*, uvlong); @@ -199,4 +200,5 @@ #pragma varargck type "I" uchar* #pragma varargck type "V" uchar* #pragma varargck type "E" uchar* +#pragma varargck type "L" uchar* #pragma varargck type "M" uchar* --- /sys/man/2/ip Sun Feb 19 14:45:55 2012 +++ /sys/man/2/ip Sun Feb 19 14:45:53 2012 @@ -1,98 +1,75 @@ .TH IP 2 .SH NAME -eipfmt, parseip, parseipmask, v4parseip, v4parsecidr, parseether, myipaddr, myetheraddr, maskip, equivip4, equivip6, defmask, isv4, v4tov6, v6tov4, nhgetv, nhgetl, nhgets, hnputv, hnputl, hnputs, ptclbsum, readipifc \- Internet Protocol addressing +eipfmt, parseip, parseipmask, v4parseip, v4parsecidr, parseether, myipaddr, myetheraddr, maskip, equivip4, equivip6, defmask, isv4, v4tov6, v6tov4, nhgetv, nhgetl, nhgets, hnputv, hnputl, hnputs, ptclbsum, freeipifc, readipifc \- Internet Protocol addressing .SH SYNOPSIS -.B #include -.br -.B #include -.br -.B #include +.de PB .PP -.B -int eipfmt(Fmt*) -.PP -.B +.ft L +.nf +.. +.PB +#include +#include +#include +.PB +int eipfmt(Fmt*) +.PB vlong parseip(uchar *ipaddr, char *str) -.PP -.B +.PB vlong parseipmask(uchar *ipaddr, char *str) -.PP -.B +.PB char* v4parseip(uchar *ipaddr, char *str) -.PP -.B +.PB ulong v4parsecidr(uchar *addr, uchar *mask, char *str) -.PP -.B -int parseether(uchar *eaddr, char *str) -.PP -.B -int myetheraddr(uchar *eaddr, char *dev) -.PP -.B -int myipaddr(uchar *ipaddr, char *net) -.PP -.B -void maskip(uchar *from, uchar *mask, uchar *to) -.PP -.B -int equivip4(uchar *ipaddr1, uchar *ipaddr2) -.PP -.B -int equivip6(uchar *ipaddr1, uchar *ipaddr2) -.PP -.B +.PB +int parseether(uchar *eaddr, char *str) +.PB +int myetheraddr(uchar *eaddr, char *dev) +.PB +int myipaddr(uchar *ipaddr, char *net) +.PB +void maskip(uchar *from, uchar *mask, uchar *to) +.PB +int equivip4(uchar *ipaddr1, uchar *ipaddr2) +.PB +int equivip6(uchar *ipaddr1, uchar *ipaddr2) +.PB uchar* defmask(uchar *ipaddr) -.PP -.B -int isv4(uchar *ipaddr) -.PP -.B -void v4tov6(uchar *ipv6, uchar *ipv4) -.PP -.B -void v6tov4(uchar *ipv4, uchar *ipv6) -.PP -.B +.PB +int isv4(uchar *ipaddr) +.PB +void v4tov6(uchar *ipv6, uchar *ipv4) +.PB +void v6tov4(uchar *ipv4, uchar *ipv6) +.PB ushort nhgets(void *p) -.PP -.B -uint nhgetl(void *p) -.PP -.B +.PB +uint nhgetl(void *p) +.PB uvlong nhgetv(void *p) -.PP -.B -void hnputs(void *p, ushort v) -.PP -.B -void hnputl(void *p, uint v) -.PP -.B -void hnputv(void *p, uvlong v) -.PP -.B +.PB +void hnputs(void *p, ushort v) +.PB +void hnputl(void *p, uint v) +.PB +void hnputv(void *p, uvlong v) +.PB ushort ptclbsum(uchar *a, int n) -.PP -.B +.PB +Ipifc* freeipifc(Ipifc *ifc) +.PB Ipifc* readipifc(char *net, Ipifc *ifc, int index) -.PP -.B +.PB uchar IPv4bcast[IPaddrlen]; -.PP -.B +.PB uchar IPv4allsys[IPaddrlen]; -.PP -.B +.PB uchar IPv4allrouter[IPaddrlen]; -.PP -.B +.PB uchar IPallbits[IPaddrlen]; -.PP -.B +.PB uchar IPnoaddr[IPaddrlen]; -.PP -.B +.PB uchar v4prefix[IPaddrlen]; .SH DESCRIPTION These routines are used by Internet Protocol (IP) programs to @@ -299,18 +276,18 @@ Iplifc *lifc; /* local addressses */ /* per ip interface */ - int index; /* number of interface in ipifc dir */ - char dev[64]; /* associated physical device */ - int mtu; /* max transfer unit */ + int index; /* number of interface in ipifc dir */ + char dev[64]; /* associated physical device */ + int mtu; /* max transfer unit */ - uchar sendra6; /* on == send router adv */ - uchar recvra6; /* on == rcv router adv */ + uchar sendra6; /* on == send router adv */ + uchar recvra6; /* on == rcv router adv */ - ulong pktin; /* packets read */ - ulong pktout; /* packets written */ - ulong errin; /* read errors */ - ulong errout; /* write errors */ - Ipv6rp rp; /* route advertisement params */ + uvlong pktin; /* packets read */ + uvlong pktout; /* packets written */ + uvlong errin; /* read errors */ + uvlong errout; /* write errors */ + Ipv6rp rp; /* route advertisement params */ } Ipifc; .EE .PP @@ -324,8 +301,8 @@ uchar ip[IPaddrlen]; uchar mask[IPaddrlen]; - uchar net[IPaddrlen]; /* ip & mask */ - ulong preflt; /* preferred lifetime */ + uchar net[IPaddrlen]; /* ip & mask */ + ulong preflt; /* preferred lifetime */ ulong validlt; /* valid lifetime */ }; .EE @@ -338,8 +315,8 @@ { int mflag; int oflag; - int maxraint; /* max route adv interval */ - int minraint; /* min route adv interval */ + int maxraint; /* max route adv interval */ + int minraint; /* min route adv interval */ int linkmtu; int reachtime; int rxmitra; @@ -357,6 +334,10 @@ if the network is multipoint or the remote address if the network is point to point. +.PP +.I Freeifc +frees memory allocated by +.IR readipifc . .SH SOURCE .B /sys/src/libip .SH SEE ALSO