DEV: tcploop: add a new "bind" command to bind to ip/port.
The Listen command automatically relies on it (without passing its argument), and both Listen and Connect now support working with the existing socket, so that it's possible to Bind an ip:port on an existing socket or to create a new one for the purpose of listening or connecting. It now becomes possible to do: tcploop 0 L1234 C8888 to connect from port 1234 to port 8888.
This commit is contained in:
parent
cb284c7a62
commit
d493331d47
@ -99,6 +99,8 @@ __attribute__((noreturn)) void usage(int code, const char *arg0)
|
||||
"actions :\n"
|
||||
" A[<count>] : Accepts <count> incoming sockets and closes count-1\n"
|
||||
" Note: fd=accept(fd)\n"
|
||||
" B[[ip]:port] : Bind a new socket to ip:port or default one if unspecified.\n"
|
||||
" Note: fd=socket,bind(fd)\n"
|
||||
" C[[ip]:port] : Connects to ip:port or default ones if unspecified.\n"
|
||||
" Note: fd=socket,connect(fd)\n"
|
||||
" D : Disconnect (connect to AF_UNSPEC)\n"
|
||||
@ -345,10 +347,21 @@ int tcp_socket()
|
||||
return sock;
|
||||
}
|
||||
|
||||
/* Try to listen to address <sa>. Return the fd or -1 in case of error */
|
||||
int tcp_listen(int sock, const struct sockaddr_storage *sa, const char *arg)
|
||||
/* Try to bind to local address <sa>. Return the fd or -1 in case of error.
|
||||
* Supports being passed NULL for arg if none has to be passed.
|
||||
*/
|
||||
int tcp_bind(int sock, const struct sockaddr_storage *sa, const char *arg)
|
||||
{
|
||||
int backlog;
|
||||
struct sockaddr_storage conn_addr;
|
||||
|
||||
if (arg && arg[1]) {
|
||||
struct err_msg err;
|
||||
|
||||
if (addr_to_ss(arg + 1, &conn_addr, &err) < 0)
|
||||
die(1, "%s\n", err.msg);
|
||||
sa = &conn_addr;
|
||||
}
|
||||
|
||||
|
||||
if (sock < 0) {
|
||||
sock = tcp_socket();
|
||||
@ -356,16 +369,6 @@ int tcp_listen(int sock, const struct sockaddr_storage *sa, const char *arg)
|
||||
return sock;
|
||||
}
|
||||
|
||||
if (arg[1])
|
||||
backlog = atoi(arg + 1);
|
||||
else
|
||||
backlog = 1000;
|
||||
|
||||
if (backlog < 0 || backlog > 65535) {
|
||||
fprintf(stderr, "backlog must be between 0 and 65535 inclusive (was %d)\n", backlog);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) {
|
||||
perror("setsockopt(SO_REUSEADDR)");
|
||||
goto fail;
|
||||
@ -383,6 +386,33 @@ int tcp_listen(int sock, const struct sockaddr_storage *sa, const char *arg)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return sock;
|
||||
fail:
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try to listen to address <sa>. Return the fd or -1 in case of error */
|
||||
int tcp_listen(int sock, const struct sockaddr_storage *sa, const char *arg)
|
||||
{
|
||||
int backlog;
|
||||
|
||||
if (sock < 0) {
|
||||
sock = tcp_bind(sock, sa, NULL);
|
||||
if (sock < 0)
|
||||
return sock;
|
||||
}
|
||||
|
||||
if (arg[1])
|
||||
backlog = atoi(arg + 1);
|
||||
else
|
||||
backlog = 1000;
|
||||
|
||||
if (backlog < 0 || backlog > 65535) {
|
||||
fprintf(stderr, "backlog must be between 0 and 65535 inclusive (was %d)\n", backlog);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (listen(sock, backlog) == -1) {
|
||||
perror("listen");
|
||||
goto fail;
|
||||
@ -798,17 +828,21 @@ int main(int argc, char **argv)
|
||||
for (arg = loop_arg; arg < argc; arg++) {
|
||||
switch (argv[arg][0]) {
|
||||
case 'L':
|
||||
/* silently ignore existing connections */
|
||||
if (sock == -1)
|
||||
sock = tcp_listen(sock, &default_addr, argv[arg]);
|
||||
sock = tcp_listen(sock, &default_addr, argv[arg]);
|
||||
if (sock < 0)
|
||||
die(1, "Fatal: tcp_listen() failed.\n");
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'B':
|
||||
/* silently ignore existing connections */
|
||||
if (sock == -1)
|
||||
sock = tcp_connect(sock, &default_addr, argv[arg]);
|
||||
sock = tcp_bind(sock, &default_addr, argv[arg]);
|
||||
if (sock < 0)
|
||||
die(1, "Fatal: tcp_connect() failed.\n");
|
||||
dolog("connect\n");
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
sock = tcp_connect(sock, &default_addr, argv[arg]);
|
||||
if (sock < 0)
|
||||
die(1, "Fatal: tcp_connect() failed.\n");
|
||||
dolog("connect\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user