From 48dce9a5751cbcf022da23fe19ce815e7b0a8860 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Thu, 19 Dec 2013 16:17:09 +1030 Subject: [PATCH] Add tcp forwarding on the listen end of an MSP connection --- commandline.c | 2 +- msp_proxy.c | 43 ++++++++++++++++++++++++++++++++----------- tests/msp | 31 +++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/commandline.c b/commandline.c index 2c786051..053e810d 100644 --- a/commandline.c +++ b/commandline.c @@ -3056,7 +3056,7 @@ struct cli_schema command_line_options[]={ "Run byte order handling test"}, {app_slip_test,{"test","slip","[--seed=]","[--duration=|--iterations=]",NULL}, 0, "Run serial encapsulation test"}, - {app_msp_connection,{"msp", "listen", "", NULL}, 0, + {app_msp_connection,{"msp", "listen", "[--once]", "[--forward=]", "", NULL}, 0, "Listen for incoming connections"}, {app_msp_connection,{"msp", "connect", "[--once]", "[--forward=]", "", "", NULL}, 0, "Connect to a remote party"}, diff --git a/msp_proxy.c b/msp_proxy.c index a12528eb..df7179a8 100644 --- a/msp_proxy.c +++ b/msp_proxy.c @@ -28,6 +28,7 @@ int saw_error=0; int once =0; struct msp_sock *listener=NULL; struct mdp_sockaddr remote_addr; +struct socket_address ip_addr; static int try_send(struct connection *conn); static void msp_poll(struct sched_ent *alarm); @@ -122,11 +123,9 @@ static void free_connection(struct connection *conn) conn->out=NULL; conn->alarm_in.poll.fd=-1; conn->alarm_out.poll.fd=-1; - DEBUGF("Freeing connection %p", conn); free(conn); if (msp_socket_count()==0){ - DEBUGF("All sockets closed"); unschedule(&mdp_sock); if (is_watching(&mdp_sock)) @@ -196,8 +195,23 @@ static int msp_listener(struct msp_sock *sock, msp_state_t state, const uint8_t struct mdp_sockaddr remote; msp_get_remote_adr(sock, &remote); INFOF(" - New connection from %s:%d", alloca_tohex_sid_t(remote.sid), remote.port); + int fd_in = STDIN_FILENO; + int fd_out = STDOUT_FILENO; - struct connection *conn = alloc_connection(sock, STDIN_FILENO, io_poll, STDOUT_FILENO, io_poll); + if (ip_addr.addrlen){ + int fd = esocket(PF_INET, SOCK_STREAM, 0); + if (fd==-1){ + msp_close(sock); + return -1; + } + if (socket_connect(fd, &ip_addr.addr, ip_addr.addrlen)==-1){ + msp_close(sock); + close(fd); + return -1; + } + fd_in = fd_out = fd; + } + struct connection *conn = alloc_connection(sock, fd_in, io_poll, fd_out, io_poll); if (!conn) return -1; @@ -390,6 +404,14 @@ int app_msp_connection(const struct cli_parsed *parsed, struct cli_context *UNUS set_nonblock(STDIN_FILENO); set_nonblock(STDOUT_FILENO); + bzero(&ip_addr, sizeof ip_addr); + + if (local_port_string){ + ip_addr.addrlen = sizeof(ip_addr.inet); + ip_addr.inet.sin_family = AF_INET; + ip_addr.inet.sin_port = htons(atoi(local_port_string)); + ip_addr.inet.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + } if (sidhex && *sidhex){ if (local_port_string){ @@ -397,17 +419,12 @@ int app_msp_connection(const struct cli_parsed *parsed, struct cli_context *UNUS listen_alarm.poll.fd = esocket(PF_INET, SOCK_STREAM, 0); if (listen_alarm.poll.fd==-1) goto end; - struct socket_address ip_addr; - ip_addr.addrlen = sizeof(ip_addr.inet); - ip_addr.inet.sin_family = AF_INET; - ip_addr.inet.sin_port = htons(atoi(local_port_string)); - ip_addr.inet.sin_addr.s_addr = INADDR_ANY; if (socket_bind(listen_alarm.poll.fd, &ip_addr.addr, ip_addr.addrlen)==-1) goto end; if (socket_listen(listen_alarm.poll.fd, 0)==-1) goto end; watch(&listen_alarm); - INFOF("- Forwarding from port %d to %s:%d", ntohs(ip_addr.inet.sin_port), alloca_tohex_sid_t(addr.sid), addr.port); + INFOF("- Forwarding from %s to %s:%d", alloca_socket_address(&ip_addr), alloca_tohex_sid_t(addr.sid), addr.port); }else{ sock = msp_socket(mdp_sock.poll.fd); once = 1; @@ -420,7 +437,6 @@ int app_msp_connection(const struct cli_parsed *parsed, struct cli_context *UNUS } }else{ sock = msp_socket(mdp_sock.poll.fd); - once = 1; msp_set_handler(sock, msp_listener, NULL); msp_set_local(sock, addr); @@ -429,7 +445,12 @@ int app_msp_connection(const struct cli_parsed *parsed, struct cli_context *UNUS goto end; listener=sock; - INFOF(" - Listening on port %d", addr.port); + if (local_port_string){ + INFOF("- Forwarding from port %d to %s", addr.port, alloca_socket_address(&ip_addr)); + }else{ + once = 1; + INFOF(" - Listening on port %d", addr.port); + } } process_msp_asap(); diff --git a/tests/msp b/tests/msp index 50c2ec24..068f1abe 100755 --- a/tests/msp +++ b/tests/msp @@ -155,7 +155,7 @@ setup_forward() { start_servald_instances +A +B } client_forward() { - executeOk --timeout=20 $servald msp connect --once --forward=2048 $1 512 + executeOk --timeout=20 $servald msp connect --once --forward=$1 $2 512 tfw_cat --stdout --stderr } test_forward() { @@ -163,11 +163,38 @@ test_forward() { fork server_hello wait_until --timeout=10 grep "Bind MDP $SIDA:512" "$instance_servald_log" set_instance +B - fork client_forward $SIDA + fork client_forward 2048 $SIDA sleep 1 executeOk nc -v 127.0.0.1 2048 < <(echo "Hello from the client") assertStdoutGrep --matches=1 "^Hello from the server$" fork_wait_all } +doc_tcp_tunnel="Tunnel a tcp connection" +setup_tcp_tunnel() { + setup_servald + assert_no_servald_processes + start_servald_instances +A +B +} +server_forward() { + executeOk_servald msp listen --once --forward=$1 512 + tfw_cat --stderr +} +nc_listen() { + execute nc -v -l $1 < <(echo "Hello from the server") + tfw_cat --stdout --stderr +} + +test_tcp_tunnel() { + fork nc_listen 6000 + set_instance +A + fork server_forward 6000 + set_instance +B + fork client_forward 6001 $SIDA + sleep 1 + executeOk nc -v 127.0.0.1 6001 < <(echo "Hello from the client") + assertStdoutGrep --matches=1 "^Hello from the server$" + fork_wait_all +} + runTests "$@"