ape/bsd/bind.c, ape/bsd/listen.c: Set local IP.
Despite what the man pages say, local addresses can actually be set so do that.
This commit is contained in:
parent
d618223086
commit
25a0d57478
4 changed files with 58 additions and 5 deletions
|
@ -39,6 +39,30 @@ _sock_inport(struct sockaddr *a)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_sock_inisany(int af, void *addr)
|
||||||
|
{
|
||||||
|
int alen;
|
||||||
|
void *any;
|
||||||
|
/* an IPv4 address that is auto-initialized to all zeros */
|
||||||
|
static struct in_addr inaddr_any;
|
||||||
|
|
||||||
|
switch(af){
|
||||||
|
case AF_INET:
|
||||||
|
alen = sizeof inaddr_any.s_addr;
|
||||||
|
any = &inaddr_any;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
alen = sizeof in6addr_any;
|
||||||
|
any = &in6addr_any;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 == memcmp(addr, any, alen);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_sock_inaddr(int af, char *ip, char *port, void *a, int *alen)
|
_sock_inaddr(int af, char *ip, char *port, void *a, int *alen)
|
||||||
{
|
{
|
||||||
|
@ -97,3 +121,23 @@ _sock_ingetaddr(Rock *r, void *a, int *alen, char *file)
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
_sock_inaddr2string(Rock *r, char *dest, int dlen)
|
||||||
|
{
|
||||||
|
int af = r->domain;
|
||||||
|
void *addr = _sock_inip(&r->addr);
|
||||||
|
int port = _sock_inport(&r->addr);
|
||||||
|
char *d = dest;
|
||||||
|
char *dend = dest+dlen;
|
||||||
|
|
||||||
|
if(!_sock_inisany(af, addr)){
|
||||||
|
inet_ntop(af, addr, d, dlen-1);
|
||||||
|
d = memchr(d, 0, dlen-1);
|
||||||
|
*(d++) = '!';
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(d, dend-d, "%d", port);
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
int
|
int
|
||||||
bind(int fd, void *a, int alen)
|
bind(int fd, void *a, int alen)
|
||||||
{
|
{
|
||||||
int n, len, cfd, port;
|
int n, len, cfd;
|
||||||
struct sockaddr *sa;
|
struct sockaddr *sa;
|
||||||
Rock *r;
|
Rock *r;
|
||||||
char msg[128];
|
char msg[128];
|
||||||
|
@ -55,17 +55,23 @@ bind(int fd, void *a, int alen)
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
port = _sock_inport(&r->addr);
|
|
||||||
snprintf(msg, sizeof msg, "bind %d", port);
|
strcpy(msg, "bind ");
|
||||||
|
_sock_inaddr2string(r, msg + 5, sizeof msg - 5);
|
||||||
|
|
||||||
n = write(cfd, msg, strlen(msg));
|
n = write(cfd, msg, strlen(msg));
|
||||||
if(n < 0){
|
if(n < 0){
|
||||||
errno = EOPNOTSUPP; /* Improve error reporting!!! */
|
errno = EOPNOTSUPP; /* Improve error reporting!!! */
|
||||||
close(cfd);
|
close(cfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(cfd);
|
close(cfd);
|
||||||
if(port <= 0)
|
|
||||||
|
if(_sock_inport(&r->addr) <= 0)
|
||||||
_sock_ingetaddr(r, &r->addr, 0, "local");
|
_sock_ingetaddr(r, &r->addr, 0, "local");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,8 @@ listen(fd, backlog)
|
||||||
close(cfd);
|
close(cfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
snprintf(msg, sizeof msg, "announce %d", _sock_inport(&r->addr));
|
strcpy(msg, "announce ");
|
||||||
|
_sock_inaddr2string(r, msg + 9, sizeof msg - 9);
|
||||||
n = write(cfd, msg, strlen(msg));
|
n = write(cfd, msg, strlen(msg));
|
||||||
if(n < 0){
|
if(n < 0){
|
||||||
errno = EOPNOTSUPP; /* Improve error reporting!!! */
|
errno = EOPNOTSUPP; /* Improve error reporting!!! */
|
||||||
|
|
|
@ -43,5 +43,7 @@ extern int _sock_data(int, char*, int, int, int, Rock**);
|
||||||
extern int _sock_ipattr(char*);
|
extern int _sock_ipattr(char*);
|
||||||
extern void* _sock_inip(struct sockaddr*);
|
extern void* _sock_inip(struct sockaddr*);
|
||||||
extern int _sock_inport(struct sockaddr*);
|
extern int _sock_inport(struct sockaddr*);
|
||||||
|
extern int _sock_inisany(int af, void *addr);
|
||||||
extern int _sock_inaddr(int, char*, char*, void*, int*);
|
extern int _sock_inaddr(int, char*, char*, void*, int*);
|
||||||
extern void _sock_ingetaddr(Rock*, void*, int*, char*);
|
extern void _sock_ingetaddr(Rock*, void*, int*, char*);
|
||||||
|
extern char* _sock_inaddr2string(Rock *r, char *dest, int dlen);
|
||||||
|
|
Loading…
Reference in a new issue