Specialize uv_xxx_getsockname, add uv_tcp_getpeername
This commit is contained in:
parent
18af13795f
commit
12b01e95f9
@ -415,6 +415,8 @@ int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
|
||||
|
||||
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
|
||||
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
|
||||
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
|
||||
int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
|
||||
|
||||
/*
|
||||
* uv_tcp_connect, uv_tcp_connect6
|
||||
@ -436,9 +438,6 @@ struct uv_connect_s {
|
||||
};
|
||||
|
||||
|
||||
int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen);
|
||||
|
||||
|
||||
/*
|
||||
* UDP support.
|
||||
*/
|
||||
@ -521,6 +520,7 @@ int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned flags);
|
||||
* 0 on success, -1 on error.
|
||||
*/
|
||||
int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags);
|
||||
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen);
|
||||
|
||||
/*
|
||||
* Send data. If the socket has not previously been bound with `uv_udp_bind`
|
||||
|
||||
@ -300,27 +300,6 @@ void uv__next(EV_P_ ev_idle* watcher, int revents) {
|
||||
}
|
||||
|
||||
|
||||
int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen) {
|
||||
socklen_t socklen;
|
||||
int saved_errno;
|
||||
|
||||
/* Don't clobber errno. */
|
||||
saved_errno = errno;
|
||||
|
||||
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
||||
socklen = (socklen_t)*namelen;
|
||||
|
||||
if (getsockname(handle->fd, name, &socklen) == -1) {
|
||||
uv_err_new(handle->loop, errno);
|
||||
} else {
|
||||
*namelen = (int)socklen;
|
||||
}
|
||||
|
||||
errno = saved_errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_ref(uv_loop_t* loop) {
|
||||
ev_ref(loop->ev);
|
||||
}
|
||||
|
||||
@ -80,6 +80,7 @@ static uv_err_code uv_translate_sys_error(int sys_errno) {
|
||||
case ECONNREFUSED: return UV_ECONNREFUSED;
|
||||
case EADDRINUSE: return UV_EADDRINUSE;
|
||||
case EADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
|
||||
case ENOTCONN: return UV_ENOTCONN;
|
||||
default: return UV_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,6 +122,54 @@ int uv_tcp_bind6(uv_tcp_t* tcp, struct sockaddr_in6 addr) {
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
|
||||
int* namelen) {
|
||||
socklen_t socklen;
|
||||
int saved_errno;
|
||||
int rv = 0;
|
||||
|
||||
/* Don't clobber errno. */
|
||||
saved_errno = errno;
|
||||
|
||||
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
||||
socklen = (socklen_t)*namelen;
|
||||
|
||||
if (getsockname(handle->fd, name, &socklen) == -1) {
|
||||
uv_err_new(handle->loop, errno);
|
||||
rv = -1;
|
||||
} else {
|
||||
*namelen = (int)socklen;
|
||||
}
|
||||
|
||||
errno = saved_errno;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
|
||||
int* namelen) {
|
||||
socklen_t socklen;
|
||||
int saved_errno;
|
||||
int rv = 0;
|
||||
|
||||
/* Don't clobber errno. */
|
||||
saved_errno = errno;
|
||||
|
||||
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
||||
socklen = (socklen_t)*namelen;
|
||||
|
||||
if (getpeername(handle->fd, name, &socklen) == -1) {
|
||||
uv_err_new(handle->loop, errno);
|
||||
rv = -1;
|
||||
} else {
|
||||
*namelen = (int)socklen;
|
||||
}
|
||||
|
||||
errno = saved_errno;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
|
||||
int r;
|
||||
|
||||
|
||||
@ -460,6 +460,30 @@ int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags) {
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
|
||||
int* namelen) {
|
||||
socklen_t socklen;
|
||||
int saved_errno;
|
||||
int rv = 0;
|
||||
|
||||
/* Don't clobber errno. */
|
||||
saved_errno = errno;
|
||||
|
||||
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
||||
socklen = (socklen_t)*namelen;
|
||||
|
||||
if (getsockname(handle->fd, name, &socklen) == -1) {
|
||||
uv_err_new(handle->loop, errno);
|
||||
rv = -1;
|
||||
} else {
|
||||
*namelen = (int)socklen;
|
||||
}
|
||||
|
||||
errno = saved_errno;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_send(uv_udp_send_t* req,
|
||||
uv_udp_t* handle,
|
||||
uv_buf_t bufs[],
|
||||
|
||||
@ -117,6 +117,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
|
||||
case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
|
||||
case WSAENETUNREACH: return UV_ENETUNREACH;
|
||||
case ERROR_OUTOFMEMORY: return UV_ENOMEM;
|
||||
case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
|
||||
case WSAENOTCONN: return UV_ENOTCONN;
|
||||
case ERROR_NOT_SUPPORTED: return UV_ENOTSUP;
|
||||
case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
|
||||
case ERROR_INVALID_FLAGS: return UV_EBADF;
|
||||
|
||||
@ -39,23 +39,6 @@ int uv_is_active(uv_handle_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
|
||||
switch (handle->type) {
|
||||
case UV_TCP:
|
||||
return uv_tcp_getsockname(loop, (uv_tcp_t*) handle, name, namelen);
|
||||
|
||||
case UV_UDP:
|
||||
return uv_udp_getsockname(loop, (uv_udp_t*) handle, name, namelen);
|
||||
|
||||
default:
|
||||
uv_set_sys_error(loop, WSAENOTSOCK);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv_close(uv_handle_t* handle, uv_close_cb cb) {
|
||||
uv_tcp_t* tcp;
|
||||
uv_pipe_t* pipe;
|
||||
|
||||
@ -123,8 +123,6 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb);
|
||||
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
|
||||
uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
|
||||
int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
struct sockaddr* name, int* namelen);
|
||||
|
||||
void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req);
|
||||
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
@ -140,9 +138,6 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
|
||||
/*
|
||||
* UDP
|
||||
*/
|
||||
int uv_udp_getsockname(uv_loop_t* loop, uv_udp_t* handle,
|
||||
struct sockaddr* name, int* namelen);
|
||||
|
||||
void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req);
|
||||
void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
|
||||
uv_udp_send_t* req);
|
||||
|
||||
@ -573,8 +573,9 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
struct sockaddr* name, int* namelen) {
|
||||
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
|
||||
int* namelen) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
int result;
|
||||
|
||||
if (handle->flags & UV_HANDLE_SHUTTING) {
|
||||
@ -592,6 +593,26 @@ int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
|
||||
int* namelen) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
int result;
|
||||
|
||||
if (handle->flags & UV_HANDLE_SHUTTING) {
|
||||
uv_set_sys_error(loop, WSAESHUTDOWN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = getpeername(handle->socket, name, namelen);
|
||||
if (result != 0) {
|
||||
uv_set_sys_error(loop, WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
|
||||
uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
|
||||
int result;
|
||||
|
||||
@ -40,8 +40,9 @@ static char uv_zero_[] = "";
|
||||
static unsigned int active_udp_streams = 0;
|
||||
|
||||
|
||||
int uv_udp_getsockname(uv_loop_t* loop, uv_udp_t* handle,
|
||||
struct sockaddr* name, int* namelen) {
|
||||
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
|
||||
int* namelen) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
int result;
|
||||
|
||||
result = getsockname(handle->socket, name, namelen);
|
||||
|
||||
@ -26,8 +26,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const int server_port = TEST_PORT;
|
||||
/* Will be updated right after making the uv_connect_call */
|
||||
static int connect_port = -1;
|
||||
|
||||
static int getsocknamecount = 0;
|
||||
static int getpeernamecount = 0;
|
||||
|
||||
static uv_loop_t* loop;
|
||||
static uv_tcp_t tcp;
|
||||
@ -72,9 +76,35 @@ static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
}
|
||||
|
||||
|
||||
static void check_sockname(struct sockaddr* addr, const char* compare_ip,
|
||||
int compare_port, const char* context) {
|
||||
struct sockaddr_in check_addr = *(struct sockaddr_in*) addr;
|
||||
struct sockaddr_in compare_addr = uv_ip4_addr(compare_ip, compare_port);
|
||||
char check_ip[17];
|
||||
int r;
|
||||
|
||||
/* Both adresses should be ipv4 */
|
||||
ASSERT(check_addr.sin_family == AF_INET);
|
||||
ASSERT(compare_addr.sin_family == AF_INET);
|
||||
|
||||
/* Check if the ip matches */
|
||||
ASSERT(memcmp(&check_addr.sin_addr,
|
||||
&compare_addr.sin_addr,
|
||||
sizeof compare_addr.sin_addr) == 0);
|
||||
|
||||
/* Check if the port matches. If port == 0 anything goes. */
|
||||
ASSERT(compare_port == 0 || check_addr.sin_port == compare_addr.sin_port);
|
||||
|
||||
r = uv_ip4_name(&check_addr, (char*) check_ip, sizeof check_ip);
|
||||
ASSERT(r == 0);
|
||||
|
||||
printf("%s: %s:%d\n", context, check_ip, ntohs(check_addr.sin_port));
|
||||
}
|
||||
|
||||
|
||||
static void on_connection(uv_stream_t* server, int status) {
|
||||
struct sockaddr sockname;
|
||||
int namelen = sizeof(sockname);
|
||||
struct sockaddr sockname, peername;
|
||||
int namelen;
|
||||
uv_handle_t* handle;
|
||||
int r;
|
||||
|
||||
@ -95,45 +125,49 @@ static void on_connection(uv_stream_t* server, int status) {
|
||||
r = uv_accept(server, (uv_stream_t*)handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
status = uv_getsockname(handle, &sockname, &namelen);
|
||||
if (status != 0) {
|
||||
fprintf(stderr, "uv_getsockname error (accepted) %d\n",
|
||||
uv_last_error(loop).code);
|
||||
}
|
||||
ASSERT(status == 0);
|
||||
|
||||
namelen = sizeof sockname;
|
||||
r = uv_tcp_getsockname((uv_tcp_t*) handle, &sockname, &namelen);
|
||||
ASSERT(r == 0);
|
||||
check_sockname(&sockname, "127.0.0.1", server_port, "accepted socket");
|
||||
getsocknamecount++;
|
||||
|
||||
namelen = sizeof peername;
|
||||
r = uv_tcp_getpeername((uv_tcp_t*) handle, &peername, &namelen);
|
||||
ASSERT(r == 0);
|
||||
check_sockname(&peername, "127.0.0.1", connect_port, "accepted socket peer");
|
||||
getpeernamecount++;
|
||||
|
||||
r = uv_read_start((uv_stream_t*)handle, alloc, after_read);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
static void on_connect(uv_connect_t* req, int status) {
|
||||
struct sockaddr sockname;
|
||||
int namelen = sizeof(sockname);
|
||||
int r;
|
||||
struct sockaddr sockname, peername;
|
||||
int r, namelen;
|
||||
|
||||
ASSERT(status == 0);
|
||||
|
||||
r = uv_getsockname((uv_handle_t*)&tcp, &sockname, &namelen);
|
||||
if (r != 0) {
|
||||
fprintf(stderr, "uv_getsockname error (connector) %d\n",
|
||||
uv_last_error(loop).code);
|
||||
}
|
||||
namelen = sizeof sockname;
|
||||
r = uv_tcp_getsockname((uv_tcp_t*) req->handle, &sockname, &namelen);
|
||||
ASSERT(r == 0);
|
||||
|
||||
check_sockname(&sockname, "127.0.0.1", 0, "connected socket");
|
||||
getsocknamecount++;
|
||||
|
||||
namelen = sizeof peername;
|
||||
r = uv_tcp_getpeername((uv_tcp_t*) req->handle, &peername, &namelen);
|
||||
ASSERT(r == 0);
|
||||
check_sockname(&peername, "127.0.0.1", server_port, "connected socket peer");
|
||||
getpeernamecount++;
|
||||
|
||||
uv_close((uv_handle_t*)&tcp, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int tcp_listener(int port) {
|
||||
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", port);
|
||||
struct sockaddr sockname;
|
||||
int namelen = sizeof(sockname);
|
||||
char ip[20];
|
||||
static int tcp_listener() {
|
||||
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", server_port);
|
||||
struct sockaddr sockname, peername;
|
||||
int namelen;
|
||||
int r;
|
||||
|
||||
r = uv_tcp_init(loop, &tcpServer);
|
||||
@ -155,30 +189,26 @@ static int tcp_listener(int port) {
|
||||
}
|
||||
|
||||
memset(&sockname, -1, sizeof sockname);
|
||||
|
||||
r = uv_getsockname((uv_handle_t*)&tcpServer, &sockname, &namelen);
|
||||
if (r != 0) {
|
||||
fprintf(stderr, "uv_getsockname error (listening) %d\n",
|
||||
uv_last_error(loop).code);
|
||||
}
|
||||
namelen = sizeof sockname;
|
||||
r = uv_tcp_getsockname(&tcpServer, &sockname, &namelen);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_ip4_name((struct sockaddr_in*)&sockname, ip, 20);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(ip[0] == '0');
|
||||
ASSERT(ip[1] == '.');
|
||||
ASSERT(ip[2] == '0');
|
||||
printf("sockname = %s\n", ip);
|
||||
|
||||
check_sockname(&sockname, "0.0.0.0", server_port, "server socket");
|
||||
getsocknamecount++;
|
||||
|
||||
namelen = sizeof sockname;
|
||||
r = uv_tcp_getpeername(&tcpServer, &peername, &namelen);
|
||||
ASSERT(r == -1);
|
||||
ASSERT(uv_last_error(loop).code == UV_ENOTCONN);
|
||||
getpeernamecount++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void tcp_connector() {
|
||||
int r;
|
||||
struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", server_port);
|
||||
struct sockaddr sockname;
|
||||
int r, namelen;
|
||||
|
||||
r = uv_tcp_init(loop, &tcp);
|
||||
tcp.data = &connect_req;
|
||||
@ -186,6 +216,14 @@ static void tcp_connector() {
|
||||
|
||||
r = uv_tcp_connect(&connect_req, &tcp, server_addr, on_connect);
|
||||
ASSERT(!r);
|
||||
|
||||
/* Fetch the actual port used by the connecting socket. */
|
||||
namelen = sizeof sockname;
|
||||
r = uv_tcp_getsockname(&tcp, &sockname, &namelen);
|
||||
ASSERT(!r);
|
||||
ASSERT(sockname.sa_family == AF_INET);
|
||||
connect_port = ntohs(((struct sockaddr_in*) &sockname)->sin_port);
|
||||
ASSERT(connect_port > 0);
|
||||
}
|
||||
|
||||
|
||||
@ -195,7 +233,6 @@ static void udp_recv(uv_udp_t* handle,
|
||||
struct sockaddr* addr,
|
||||
unsigned flags) {
|
||||
struct sockaddr sockname;
|
||||
char ip[20];
|
||||
int namelen;
|
||||
int r;
|
||||
|
||||
@ -206,17 +243,11 @@ static void udp_recv(uv_udp_t* handle,
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&sockname, -1, sizeof sockname);
|
||||
namelen = sizeof(sockname);
|
||||
r = uv_getsockname((uv_handle_t*)&udp, &sockname, &namelen);
|
||||
if (r != 0) {
|
||||
fprintf(stderr, "uv_getsockname error (connector) %d\n", uv_last_error(loop).code);
|
||||
}
|
||||
r = uv_udp_getsockname(&udp, &sockname, &namelen);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_ip4_name((struct sockaddr_in*)&sockname, ip, 20);
|
||||
ASSERT(r == 0);
|
||||
printf("sockname = %s\n", ip);
|
||||
|
||||
check_sockname(&sockname, "0.0.0.0", 0, "udp receiving socket");
|
||||
getsocknamecount++;
|
||||
|
||||
uv_close((uv_handle_t*) &udp, NULL);
|
||||
@ -229,11 +260,10 @@ static void udp_send(uv_udp_send_t* req, int status) {
|
||||
}
|
||||
|
||||
|
||||
static int udp_listener(int port) {
|
||||
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", port);
|
||||
static int udp_listener() {
|
||||
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", server_port);
|
||||
struct sockaddr sockname;
|
||||
int namelen = sizeof(sockname);
|
||||
char ip[20];
|
||||
int namelen;
|
||||
int r;
|
||||
|
||||
r = uv_udp_init(loop, &udpServer);
|
||||
@ -249,20 +279,10 @@ static int udp_listener(int port) {
|
||||
}
|
||||
|
||||
memset(&sockname, -1, sizeof sockname);
|
||||
|
||||
r = uv_getsockname((uv_handle_t*)&udpServer, &sockname, &namelen);
|
||||
if (r != 0) {
|
||||
fprintf(stderr, "uv_getsockname error (listening) %d\n", uv_last_error(loop).code);
|
||||
}
|
||||
namelen = sizeof sockname;
|
||||
r = uv_udp_getsockname(&udpServer, &sockname, &namelen);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_ip4_name((struct sockaddr_in*)&sockname, ip, 20);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(ip[0] == '0');
|
||||
ASSERT(ip[1] == '.');
|
||||
ASSERT(ip[2] == '0');
|
||||
printf("sockname = %s\n", ip);
|
||||
|
||||
check_sockname(&sockname, "0.0.0.0", server_port, "udp listener socket");
|
||||
getsocknamecount++;
|
||||
|
||||
r = uv_udp_recv_start(&udpServer, alloc, udp_recv);
|
||||
@ -281,7 +301,7 @@ static void udp_sender(void) {
|
||||
ASSERT(!r);
|
||||
|
||||
buf = uv_buf_init("PING", 4);
|
||||
server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
server_addr = uv_ip4_addr("127.0.0.1", server_port);
|
||||
|
||||
r = uv_udp_send(&send_req, &udp, &buf, 1, server_addr, udp_send);
|
||||
ASSERT(!r);
|
||||
@ -292,7 +312,7 @@ TEST_IMPL(getsockname_tcp) {
|
||||
uv_init();
|
||||
loop = uv_default_loop();
|
||||
|
||||
if (tcp_listener(TEST_PORT))
|
||||
if (tcp_listener())
|
||||
return 1;
|
||||
|
||||
tcp_connector();
|
||||
@ -300,6 +320,7 @@ TEST_IMPL(getsockname_tcp) {
|
||||
uv_run(loop);
|
||||
|
||||
ASSERT(getsocknamecount == 3);
|
||||
ASSERT(getpeernamecount == 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -309,7 +330,7 @@ TEST_IMPL(getsockname_udp) {
|
||||
uv_init();
|
||||
loop = uv_default_loop();
|
||||
|
||||
if (udp_listener(TEST_PORT))
|
||||
if (udp_listener())
|
||||
return 1;
|
||||
|
||||
udp_sender();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user