|
|
|
|
@ -25,7 +25,8 @@ typedef struct {
|
|
|
|
|
struct sockaddr_storage sockname,
|
|
|
|
|
peername;
|
|
|
|
|
unsigned int open:1,
|
|
|
|
|
bound:1;
|
|
|
|
|
bound:1,
|
|
|
|
|
connected:1;
|
|
|
|
|
} socket_t;
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
@ -360,6 +361,7 @@ int close(int fd) {
|
|
|
|
|
goto do_close;
|
|
|
|
|
|
|
|
|
|
s->open = 0;
|
|
|
|
|
s->connected = 0;
|
|
|
|
|
if (s->used_domain == AF_UNIX && s->wanted_domain != AF_UNIX && s->unix_path[0])
|
|
|
|
|
unlink(s->unix_path);
|
|
|
|
|
goto do_close;
|
|
|
|
|
@ -374,7 +376,7 @@ int getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen) {
|
|
|
|
|
check_bind(fd);
|
|
|
|
|
|
|
|
|
|
const char *err;
|
|
|
|
|
int (*real_getsockname)(int) = dlsym(RTLD_NEXT, "getsockname");
|
|
|
|
|
int (*real_getsockname)(int, struct sockaddr *, socklen_t *) = dlsym(RTLD_NEXT, "getsockname");
|
|
|
|
|
err = "fd out of bounds";
|
|
|
|
|
if (fd < 0 || fd >= MAX_SOCKETS)
|
|
|
|
|
goto do_getsockname_warn;
|
|
|
|
|
@ -408,14 +410,16 @@ int getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen) {
|
|
|
|
|
do_getsockname_warn:
|
|
|
|
|
fprintf(stderr, "preload getsockname(): %s (fd %i)\n", err, fd);
|
|
|
|
|
do_getsockname:
|
|
|
|
|
return real_getsockname(fd);
|
|
|
|
|
return real_getsockname(fd, addr, addrlen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen) {
|
|
|
|
|
check_bind(fd);
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "************* getpeername\n");
|
|
|
|
|
|
|
|
|
|
const char *err;
|
|
|
|
|
int (*real_getpeername)(int) = dlsym(RTLD_NEXT, "getpeername");
|
|
|
|
|
int (*real_getpeername)(int, struct sockaddr *, socklen_t *) = dlsym(RTLD_NEXT, "getpeername");
|
|
|
|
|
err = "fd out of bounds";
|
|
|
|
|
if (fd < 0 || fd >= MAX_SOCKETS)
|
|
|
|
|
goto do_getpeername_warn;
|
|
|
|
|
@ -424,6 +428,8 @@ int getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen) {
|
|
|
|
|
goto do_getpeername;
|
|
|
|
|
if (s->used_domain != AF_UNIX || s->wanted_domain == AF_UNIX || !s->bound)
|
|
|
|
|
goto do_getpeername;
|
|
|
|
|
if (!s->connected)
|
|
|
|
|
goto do_getpeername;
|
|
|
|
|
|
|
|
|
|
switch (s->wanted_domain) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
@ -449,18 +455,19 @@ int getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen) {
|
|
|
|
|
do_getpeername_warn:
|
|
|
|
|
fprintf(stderr, "preload getpeername(): %s (fd %i)\n", err, fd);
|
|
|
|
|
do_getpeername:
|
|
|
|
|
return real_getpeername(fd);
|
|
|
|
|
return real_getpeername(fd, addr, addrlen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int connect(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
|
|
|
|
check_bind(fd);
|
|
|
|
|
|
|
|
|
|
socket_t *s = NULL;
|
|
|
|
|
const char *err;
|
|
|
|
|
int (*real_connect)(int, const struct sockaddr *, socklen_t) = dlsym(RTLD_NEXT, "connect");
|
|
|
|
|
err = "fd out of bounds";
|
|
|
|
|
if (fd < 0 || fd >= MAX_SOCKETS)
|
|
|
|
|
goto do_connect_warn;
|
|
|
|
|
socket_t *s = &real_sockets[fd];
|
|
|
|
|
s = &real_sockets[fd];
|
|
|
|
|
err = "fd not open";
|
|
|
|
|
if (!s->open)
|
|
|
|
|
goto do_connect_warn;
|
|
|
|
|
@ -489,8 +496,11 @@ int connect(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
|
|
|
|
|
|
|
|
|
do_connect_warn:
|
|
|
|
|
fprintf(stderr, "preload connect(): %s (fd %i)\n", err, fd);
|
|
|
|
|
do_connect:
|
|
|
|
|
return real_connect(fd, addr, addrlen);
|
|
|
|
|
do_connect:;
|
|
|
|
|
int ret = real_connect(fd, addr, addrlen);
|
|
|
|
|
if (ret == 0 && s)
|
|
|
|
|
s->connected = 1;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int accept(int fd, struct sockaddr *addr, socklen_t *addrlen) {
|
|
|
|
|
|