X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Fnet.c;h=0f7be541cf4b82c1b27f8c74d3e14c82ff587fb2;hb=0a1bc5b19fe40d88790d02f236ea4c9637024969;hp=866e1362da1a4e06a72838d903f7e1c6828dd8ec;hpb=fc7f77350c92848eaf5903e49b5b9815fb3b96ea;p=doldaconnect.git diff --git a/daemon/net.c b/daemon/net.c index 866e136..0f7be54 100644 --- a/daemon/net.c +++ b/daemon/net.c @@ -544,50 +544,6 @@ size_t sockqueuesize(struct socket *sk) return(ret); } -struct socket *netcslisten(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data) -{ - struct socket *sk; - int intbuf; - - if(confgetint("net", "mode") == 1) - { - errno = EOPNOTSUPP; - return(NULL); - } - /* I don't know if this is actually correct (it probably isn't), - * but since, at on least Linux systems, PF_* are specifically - * #define'd to their AF_* counterparts, it allows for a severely - * smoother implementation. If it breaks something on your - * platform, please tell me so. - */ - if(confgetint("net", "mode") == 0) - { - if((sk = mksock(name->sa_family, type)) == NULL) - return(NULL); - sk->state = SOCK_LST; - if(confgetint("net", "reuseaddr")) - { - intbuf = 1; - setsockopt(sk->fd, SOL_SOCKET, SO_REUSEADDR, &intbuf, sizeof(intbuf)); - } - if(bind(sk->fd, name, namelen) < 0) - { - putsock(sk); - return(NULL); - } - if(listen(sk->fd, 16) < 0) - { - putsock(sk); - return(NULL); - } - sk->acceptcb = func; - sk->data = data; - return(sk); - } - errno = EOPNOTSUPP; - return(NULL); -} - /* * The difference between netcslisten() and netcslistenlocal() is that * netcslistenlocal() always listens on the local host, instead of @@ -630,6 +586,54 @@ struct socket *netcslistenlocal(int type, struct sockaddr *name, socklen_t namel return(sk); } +struct socket *netcslisten(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data) +{ + if(confgetint("net", "mode") == 1) + { + errno = EOPNOTSUPP; + return(NULL); + } + /* I don't know if this is actually correct (it probably isn't), + * but since, at on least Linux systems, PF_* are specifically + * #define'd to their AF_* counterparts, it allows for a severely + * smoother implementation. If it breaks something on your + * platform, please tell me so. + */ + if(confgetint("net", "mode") == 0) + return(netcslistenlocal(type, name, namelen, func, data)); + errno = EOPNOTSUPP; + return(NULL); +} + +struct socket *netcstcplisten(int port, int local, void (*func)(struct socket *, struct socket *, void *), void *data) +{ + struct sockaddr_in addr; +#ifdef HAVE_IPV6 + struct sockaddr_in6 addr6; +#endif + struct socket *(*csfunc)(int, struct sockaddr *, socklen_t, void (*)(struct socket *, struct socket *, void *), void *); + struct socket *ret; + + if(local) + csfunc = netcslistenlocal; + else + csfunc = netcslisten; +#ifdef HAVE_IPV6 + memset(&addr6, 0, sizeof(addr6)); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = htons(port); + addr6.sin6_addr = in6addr_any; + if((ret = csfunc(SOCK_STREAM, (struct sockaddr *)&addr6, sizeof(addr6), func, data)) != NULL) + return(ret); + if((ret == NULL) && (errno != EAFNOSUPPORT)) + return(NULL); +#endif + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + return(csfunc(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), func, data)); +} + struct socket *netcsdgram(struct sockaddr *name, socklen_t namelen) { struct socket *sk; @@ -1092,6 +1096,40 @@ int sockgetremotename(struct socket *sk, struct sockaddr **namebuf, socklen_t *l } } +int addreq(struct sockaddr *x, struct sockaddr *y) +{ + struct sockaddr_un *u1, *u2; + struct sockaddr_in *n1, *n2; +#ifdef HAVE_IPV6 + struct sockaddr_in6 *s1, *s2; +#endif + + if(x->sa_family != y->sa_family) + return(0); + switch(x->sa_family) { + case AF_UNIX: + u1 = (struct sockaddr_un *)x; u2 = (struct sockaddr_un *)y; + if(strncmp(u1->sun_path, u2->sun_path, sizeof(u1->sun_path))) + return(0); + break; + case AF_INET: + n1 = (struct sockaddr_in *)x; n2 = (struct sockaddr_in *)y; + if(n1->sin_port != n2->sin_port) + return(0); + if(n1->sin_addr.s_addr != n2->sin_addr.s_addr) + return(0); + break; + case AF_INET6: + s1 = (struct sockaddr_in6 *)x; s2 = (struct sockaddr_in6 *)y; + if(s1->sin6_port != s2->sin6_port) + return(0); + if(memcmp(s1->sin6_addr.s6_addr, s2->sin6_addr.s6_addr, sizeof(s1->sin6_addr.s6_addr))) + return(0); + break; + } + return(1); +} + char *formataddress(struct sockaddr *arg, socklen_t arglen) { struct sockaddr_un *UNIX; /* Some wise guy has #defined unix with