mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-25 02:55:15 +00:00
Updated client-side TCP forwarding command line options
This commit is contained in:
parent
b1d7a78adf
commit
d6b48fe4e1
26
src/client.c
26
src/client.c
@ -1372,31 +1372,39 @@ send_login(char *login, int len)
|
||||
{
|
||||
uint8_t flags = 0, data[100];
|
||||
int length = 17, addrlen = 0;
|
||||
uint16_t port;
|
||||
|
||||
if (len != 16)
|
||||
DEBUG(1, "Login calculated incorrect length hash! len=%d", len);
|
||||
|
||||
memcpy(data + 1, login, 16);
|
||||
|
||||
if (this.remote_forward_port > 0) {
|
||||
if (this.remote_forward_addr.ss_family != AF_UNSPEC) {
|
||||
struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &this.remote_forward_addr;
|
||||
struct sockaddr_in *s = (struct sockaddr_in *) &this.remote_forward_addr;
|
||||
|
||||
port = (this.remote_forward_addr.ss_family == AF_INET ? s->sin_port : s6->sin6_port);
|
||||
|
||||
*(uint16_t *) (data + length) = port;
|
||||
|
||||
flags |= 1;
|
||||
*(uint16_t *) (data + length) = (uint16_t) this.remote_forward_port;
|
||||
length += 2;
|
||||
/* set remote IP to be non-localhost if this.remote_forward_addr set */
|
||||
if (this.remote_forward_addr_len) {
|
||||
if (this.remote_forward_addr.ss_family == AF_INET && s->sin_addr.s_addr != INADDR_LOOPBACK) {
|
||||
if (this.remote_forward_addr.ss_family == AF_INET6) { /* IPv6 address */
|
||||
addrlen = sizeof(struct in6_addr);
|
||||
addrlen = sizeof(s6);
|
||||
flags |= 4;
|
||||
memcpy(data + length, &((struct sockaddr_in6 *) &this.remote_forward_addr)->sin6_addr, addrlen);
|
||||
memcpy(data + length, &s6->sin6_addr, addrlen);
|
||||
} else { /* IPv4 address */
|
||||
flags |= 2;
|
||||
addrlen = sizeof(struct in_addr);
|
||||
memcpy(data + length, &((struct sockaddr_in *) &this.remote_forward_addr)->sin_addr, addrlen);
|
||||
addrlen = sizeof(s);
|
||||
memcpy(data + length, &s->sin_addr, addrlen);
|
||||
}
|
||||
|
||||
length += addrlen;
|
||||
}
|
||||
DEBUG(2, "Sending TCP forward login request: port %d, length %d, addr %d",
|
||||
this.remote_forward_port, length, addrlen);
|
||||
DEBUG(2, "Sending TCP forward login request: port %hu, length %d, addrlen %d",
|
||||
port, length, addrlen);
|
||||
}
|
||||
|
||||
data[0] = flags;
|
||||
|
@ -46,8 +46,7 @@ struct client_instance {
|
||||
|
||||
/* Remote TCP forwarding stuff (for -R) */
|
||||
struct sockaddr_storage remote_forward_addr;
|
||||
socklen_t remote_forward_addr_len; /* 0 if connecting to localhost */
|
||||
int remote_forward_port; /* 0 if no forwarding used */
|
||||
int use_remote_forward; /* 0 if no forwarding used */
|
||||
|
||||
int tun_fd;
|
||||
int dns_fd;
|
||||
|
107
src/iodine.c
107
src/iodine.c
@ -81,7 +81,8 @@ struct client_instance this;
|
||||
.maxfragsize_up = 100, \
|
||||
.next_downstream_ack = -1, \
|
||||
.num_immediate = 1, \
|
||||
.rtt_total_ms = 200
|
||||
.rtt_total_ms = 200, \
|
||||
.remote_forward_addr = {.ss_family = AF_UNSPEC}
|
||||
|
||||
static struct client_instance preset_default = {
|
||||
.raw_mode = 1,
|
||||
@ -302,6 +303,62 @@ version()
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_tcp_forward_option()
|
||||
{
|
||||
char *remote_port_str, *remote_host_str;
|
||||
int retval;
|
||||
|
||||
if (strrchr(optarg, ':')) {
|
||||
remote_port_str = strrchr(optarg, ':') + 1;
|
||||
if (optarg[0] == '[') {
|
||||
/* IPv6 address enclosed in square brackets */
|
||||
remote_host_str = optarg + 1;
|
||||
/* replace closing bracket with null terminator */
|
||||
*strchr(remote_host_str, ']') = 0;
|
||||
this.remote_forward_addr.ss_family = AF_INET6;
|
||||
retval = inet_pton(AF_INET6, remote_host_str,
|
||||
&((struct sockaddr_in6 *) &this.remote_forward_addr)->sin6_addr);
|
||||
} else {
|
||||
remote_host_str = optarg;
|
||||
/* replace separator with null terminator */
|
||||
*strchr(remote_host_str, ':') = 0;
|
||||
this.remote_forward_addr.ss_family = AF_INET;
|
||||
retval = inet_aton(remote_host_str,
|
||||
&((struct sockaddr_in *) &this.remote_forward_addr)->sin_addr);
|
||||
}
|
||||
} else {
|
||||
/* no address specified (use server localhost IPv4), optarg is port */
|
||||
remote_port_str = optarg;
|
||||
this.remote_forward_addr.ss_family = AF_INET;
|
||||
((struct sockaddr_in *) &this.remote_forward_addr)->sin_addr.s_addr = INADDR_LOOPBACK;
|
||||
}
|
||||
|
||||
if (retval <= 0) {
|
||||
errx(12, "Invalid remote forward address (-R)! Must be [host:]port,\n"
|
||||
"where IPv6 addresses are enclosed in literal square brackets [].");
|
||||
usage();
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
/* parse port */
|
||||
int port = atoi(remote_port_str);
|
||||
if (port < 1 || port > 65535) {
|
||||
fprintf(stderr, "Remote forward (-R) TCP port must be between 1 and 65535.");
|
||||
usage();
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
if (this.remote_forward_addr.ss_family == AF_INET) {
|
||||
/* set port as sockaddr_in (IPv4) */
|
||||
((struct sockaddr_in *) &this.remote_forward_addr)->sin_port = port;
|
||||
} else {
|
||||
/* set port in IPv6 sockaddr */
|
||||
((struct sockaddr_in6 *) &this.remote_forward_addr)->sin6_port = port;
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -318,7 +375,7 @@ main(int argc, char **argv)
|
||||
char *device = NULL;
|
||||
char *pidfile = NULL;
|
||||
|
||||
char *remote_host_str = NULL, *remote_port_str = NULL;
|
||||
int remote_forward_port;
|
||||
|
||||
char *nameserv_host = NULL;
|
||||
struct sockaddr_storage nameservaddr;
|
||||
@ -452,40 +509,8 @@ main(int argc, char **argv)
|
||||
case 'R':
|
||||
/* Argument format: [host:]port */
|
||||
if (!optarg) break;
|
||||
|
||||
if (strrchr(optarg, ':')) {
|
||||
remote_port_str = strrchr(optarg, ':') + 1;
|
||||
if (optarg[0] == '[') {
|
||||
/* IPv6 address enclosed in square brackets */
|
||||
remote_host_str = optarg + 1;
|
||||
/* replace closing bracket with null terminator */
|
||||
*strchr(remote_host_str, ']') = 0;
|
||||
this.remote_forward_addr.ss_family = AF_INET6;
|
||||
retval = inet_pton(AF_INET6, remote_host_str,
|
||||
&((struct sockaddr_in6 *) &this.remote_forward_addr)->sin6_addr);
|
||||
} else {
|
||||
remote_host_str = optarg;
|
||||
/* replace separator with null terminator */
|
||||
*strchr(remote_host_str, ':') = 0;
|
||||
this.remote_forward_addr.ss_family = AF_INET;
|
||||
retval = inet_aton(remote_host_str,
|
||||
&((struct sockaddr_in *) &this.remote_forward_addr)->sin_addr);
|
||||
}
|
||||
} else {
|
||||
/* no address specified, optarg is port */
|
||||
remote_port_str = optarg;
|
||||
}
|
||||
|
||||
/* parse port */
|
||||
this.remote_forward_port = atoi(remote_port_str);
|
||||
if (this.remote_forward_port < 0 || this.remote_forward_port > 65535)
|
||||
this.remote_forward_port = -1;
|
||||
|
||||
if (retval <= 0) {
|
||||
errx(12, "Invalid remote TCP forwarding specification! Check help for info.");
|
||||
usage();
|
||||
/* not reached */
|
||||
}
|
||||
this.use_remote_forward = 1;
|
||||
remote_forward_port = parse_tcp_forward_option();
|
||||
break;
|
||||
case OPT_NODROP:
|
||||
// TODO implement TCP-over-tun optimisations
|
||||
@ -587,11 +612,7 @@ main(int argc, char **argv)
|
||||
this.foreground = 1;
|
||||
}
|
||||
|
||||
if (this.remote_forward_port == -1) {
|
||||
fprintf(stderr, "Remote TCP port must be between 1 and 65535.");
|
||||
usage();
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
|
||||
this.nameserv_hosts_len = argc - 1;
|
||||
if (this.nameserv_hosts_len <= 0)
|
||||
@ -712,9 +733,9 @@ main(int argc, char **argv)
|
||||
(a != this.nameserv_addrs_len - 1) ? ", " : "");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (this.remote_forward_port)
|
||||
if (this.remote_forward_addr.ss_family != AF_UNSPEC)
|
||||
fprintf(stderr, "Requesting TCP data forwarding from server to %s:%d\n",
|
||||
format_addr(&this.remote_forward_addr, sizeof(struct sockaddr_storage)), this.remote_forward_port);
|
||||
format_addr(&this.remote_forward_addr, sizeof(struct sockaddr_storage)), remote_forward_port);
|
||||
|
||||
if (client_handshake()) {
|
||||
retval = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user