From 020634e1e84ab6063b0b403432002073bdaffe09 Mon Sep 17 00:00:00 2001 From: Masaq- <tilt@techie.com> Date: Wed, 30 Jan 2019 22:42:00 +0000 Subject: short command line options -w -a -t --- src/options.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/options.h') diff --git a/src/options.h b/src/options.h index 176620a..f0dd7d8 100644 --- a/src/options.h +++ b/src/options.h @@ -88,6 +88,9 @@ struct options { int udp; /** unpriviledged mode */ int unprivileged; + uint16_t window_size; + uint16_t ack_interval; + uint16_t resend_interval; #ifndef WIN32 /** run as daemon if non zero value */ -- cgit v1.2.3 From dfb47d868a46b8d3aacc8ee1446fa9302e047a79 Mon Sep 17 00:00:00 2001 From: Masaq- <tilt@techie.com> Date: Fri, 8 Feb 2019 04:17:50 +0000 Subject: command line option -y payload size --- src/options.c | 7 ++++++- src/options.h | 1 + src/pconfig.h | 2 +- src/pdesc.c | 1 + src/pdesc.h | 3 ++- src/pkt.c | 7 +++++++ src/ptunnel.c | 10 +++++----- 7 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src/options.h') diff --git a/src/options.c b/src/options.c index f1080aa..f6dba79 100644 --- a/src/options.c +++ b/src/options.c @@ -384,7 +384,7 @@ int parse_options(int argc, char **argv) { * since you have to pass long options as '--option=value'. Commonly used * '--option value' is *NOT* allowed for some libc implementations. */ - c = getopt_long(argc, argv, "m:p:l:r::R::c:v:L::o::sP:d::Su::g::C::e::w:a:t:h", &long_options[0], &oidx); + c = getopt_long(argc, argv, "m:p:l:r::R::c:v:L::o::sP:d::Su::g::C::e::w:a:t:y:h", &long_options[0], &oidx); if (c == -1) break; switch (c) { @@ -548,6 +548,11 @@ int parse_options(int argc, char **argv) { break; opts.resend_interval = atoi(optarg); break; + case 'y': + if (!optarg) + break; + opts.payload_size = atoi(optarg); + break; case 'h': print_usage(argv[0]); exit(EXIT_SUCCESS); diff --git a/src/options.h b/src/options.h index f0dd7d8..b180ef5 100644 --- a/src/options.h +++ b/src/options.h @@ -91,6 +91,7 @@ struct options { uint16_t window_size; uint16_t ack_interval; uint16_t resend_interval; + uint16_t payload_size; #ifndef WIN32 /** run as daemon if non zero value */ diff --git a/src/pconfig.h b/src/pconfig.h index 6be141e..e13f7ee 100644 --- a/src/pconfig.h +++ b/src/pconfig.h @@ -75,7 +75,7 @@ enum { * we send. Note that this does not include * the IP or ICMP headers! */ - kDefault_buf_size = 1024, + kDefault_buf_size = 0xFFFF, /** Type code for echo request and replies */ kICMP_echo_request = 8, kICMP_echo_reply = 0, diff --git a/src/pdesc.c b/src/pdesc.c index b034b8b..df8df46 100644 --- a/src/pdesc.c +++ b/src/pdesc.c @@ -114,6 +114,7 @@ proxy_desc_t *create_and_insert_proxy_desc(uint16_t id_no, uint16_t icmp_id, cur->window_size = opts.window_size ? opts.window_size : 64; cur->ack_interval = opts.ack_interval ? opts.ack_interval / 1000.0 : 1.0; cur->resend_interval = opts.resend_interval ? opts.resend_interval / 1000.0 : 1.5; + cur->payload_size = opts.payload_size ? opts.payload_size : 1024; memset(cur->extended_options, 0, sizeof(cur->extended_options)); cur->send_ring = calloc(cur->window_size, sizeof(icmp_desc_t)); cur->recv_ring = calloc(cur->window_size, sizeof(forward_desc_t *)); diff --git a/src/pdesc.h b/src/pdesc.h index d4c463d..a537b9a 100644 --- a/src/pdesc.h +++ b/src/pdesc.h @@ -159,7 +159,8 @@ typedef struct proxy_desc_t { uint16_t window_size; double ack_interval; double resend_interval; - uint16_t extended_options[3]; + uint16_t payload_size; + uint16_t extended_options[4]; icmp_desc_t *send_ring; forward_desc_t **recv_ring; xfer_stats_t xfer; diff --git a/src/pkt.c b/src/pkt.c index e249ca3..6af69bc 100644 --- a/src/pkt.c +++ b/src/pkt.c @@ -361,6 +361,9 @@ void handle_data(icmp_echo_packet_t *pkt, int total_len, forward_desc_t *ring[], if (pt_pkt->data_len >= 6) { cur->extended_options[2] = ntohs(extended_options[2]); } + if (pt_pkt->data_len >= 8) { + cur->extended_options[3] = ntohs(extended_options[3]); + } return; } if (pt_pkt->seq_no == *next_expected_seq) { @@ -439,6 +442,10 @@ void handle_extended_options(void *vcur) cur->resend_interval = cur->extended_options[2] / 1000.0; pt_log(kLog_verbose, "Received extended option for resend interval %f \n", cur->resend_interval); } + if (cur->extended_options[3] > 0) { + cur->payload_size = cur->extended_options[3]; + pt_log(kLog_verbose, "Received extended option for payload size %d \n", cur->payload_size); + } } void handle_ack(uint16_t seq_no, icmp_desc_t ring[], int *packets_awaiting_ack, diff --git a/src/ptunnel.c b/src/ptunnel.c index c87fa3f..3f5975d 100644 --- a/src/ptunnel.c +++ b/src/ptunnel.c @@ -88,7 +88,6 @@ uint32_t num_tunnels = 0; uint32_t *seq_expiry_tbl = NULL; /* Some buffer constants */ -const int tcp_receive_buf_len = kDefault_buf_size; const int icmp_receive_buf_len = kDefault_buf_size + kIP_header_size + kICMP_header_size + sizeof(ping_tunnel_pkt_t); const int pcap_buf_size = (kDefault_buf_size + kIP_header_size + @@ -560,12 +559,13 @@ void* pt_proxy(void *args) { cur->last_ack = time_as_double(); uint16_t *extended_options = 0; size_t extended_options_size = 0; - if (opts.window_size || opts.ack_interval || opts.resend_interval) { - extended_options = calloc(3, sizeof(uint16_t)); - extended_options_size = 3*sizeof(uint16_t); + if (opts.window_size || opts.ack_interval || opts.resend_interval || opts.payload_size) { + extended_options = calloc(4, sizeof(uint16_t)); + extended_options_size = 4*sizeof(uint16_t); extended_options[0] = htons(opts.window_size); extended_options[1] = htons(opts.ack_interval); extended_options[2] = htons(opts.resend_interval); + extended_options[3] = htons(opts.payload_size); } queue_packet(fwd_sock, cur->pkt_type, (char *)extended_options, extended_options_size, cur->id_no, cur->id_no, &cur->my_seq, cur->send_ring, &cur->send_idx, &cur->send_wait_ack, @@ -587,7 +587,7 @@ void* pt_proxy(void *args) { } /* Handle TCP traffic */ if (FD_ISSET(cur->sock, &set)) { - bytes = recv(cur->sock, cur->buf, tcp_receive_buf_len, 0); + bytes = recv(cur->sock, cur->buf, cur->payload_size, 0); if (bytes <= 0) { pt_log(kLog_info, "Connection closed or lost.\n"); tmp = cur->next; -- cgit v1.2.3 From 3245b7777503e1edb8e0a98d2375b3802ca29ee1 Mon Sep 17 00:00:00 2001 From: Masaq- <tilt@techie.com> Date: Thu, 21 Feb 2019 05:11:07 +0000 Subject: -E --empty-pings compensate for ICMP sequence number inspection --- src/options.c | 15 +++++++++++++-- src/options.h | 1 + src/pkt.c | 5 ++++- src/ptunnel.c | 10 ++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src/options.h') diff --git a/src/options.c b/src/options.c index 85b8a9c..66c44a6 100644 --- a/src/options.c +++ b/src/options.c @@ -144,7 +144,7 @@ static const struct option_usage usage[] = { /** --ack-interval */ {"milliseconds", 0, OPT_DEC32, {.unum = 1000}, "Tune the explicit acknowledgement interval (in milliseconds)\n" - "Decreasing the acknowlegement interval can improve NAT stability.\n" + "Decreasing the acknowledgement interval can improve NAT stability.\n" }, /** --resend-interval */ {"milliseconds", 0, OPT_DEC32, {.unum = 1500}, @@ -157,6 +157,11 @@ static const struct option_usage usage[] = { "Decreasing the payload size can avoid corruption of large packets.\n" "Increasing the payload size can compensate for out-of-order delivery.\n" }, + /** --empty-pings */ + {"count", 0, OPT_DEC32, {.unum = 0}, + "Tune the number of empty pings to send with each explicit acknowledgement.\n" + "Empty pings can compensate for ICMP sequence number inspection.\n" + }, /** --daemon */ {"pidfile", 0, OPT_STR, {.str = "/run/ptunnel.pid"}, #ifdef WIN32 @@ -223,6 +228,7 @@ static struct option long_options[] = { {"ack-interval", required_argument, 0, 'a'}, {"resend-interval", required_argument, 0, 't'}, {"payload-size", required_argument, 0, 'y'}, + {"empty-pings", required_argument, 0, 'E'}, {"daemon", optional_argument, 0, 'd'}, {"syslog", no_argument, 0, 'S'}, {"user", optional_argument, 0, 'u'}, @@ -409,7 +415,7 @@ int parse_options(int argc, char **argv) { * since you have to pass long options as '--option=value'. Commonly used * '--option value' is *NOT* allowed for some libc implementations. */ - c = getopt_long(argc, argv, "m:p:l:r::R::c:v:L::o::sP:d::Su::g::C::e::w:a:t:y:h", &long_options[0], &oidx); + c = getopt_long(argc, argv, "m:p:l:r::R::c:v:L::o::sP:d::Su::g::C::e::w:a:t:y:E:h", &long_options[0], &oidx); if (c == -1) break; switch (c) { @@ -578,6 +584,11 @@ int parse_options(int argc, char **argv) { break; opts.payload_size = atoi(optarg); break; + case 'E': + if (!optarg) + break; + opts.empty_pings = atoi(optarg); + break; case 'h': print_usage(argv[0]); exit(EXIT_SUCCESS); diff --git a/src/options.h b/src/options.h index b180ef5..7afcfec 100644 --- a/src/options.h +++ b/src/options.h @@ -92,6 +92,7 @@ struct options { uint16_t ack_interval; uint16_t resend_interval; uint16_t payload_size; + uint16_t empty_pings; #ifndef WIN32 /** run as daemon if non zero value */ diff --git a/src/pkt.c b/src/pkt.c index 1d3d1b6..e2fd2a8 100644 --- a/src/pkt.c +++ b/src/pkt.c @@ -96,6 +96,7 @@ void handle_packet(char *buf, unsigned bytes, int is_pcap, struct sockaddr_in *a if (ntohl(pt_pkt->magic) == opts.magic) { pt_pkt->state = ntohl(pt_pkt->state); pkt->identifier = ntohs(pkt->identifier); + pkt->seq = ntohs(pkt->seq); pt_pkt->id_no = ntohs(pt_pkt->id_no); pt_pkt->seq_no = ntohs(pt_pkt->seq_no); /* Find the relevant connection, if it exists */ @@ -114,8 +115,10 @@ void handle_packet(char *buf, unsigned bytes, int is_pcap, struct sockaddr_in *a */ if (cur) { type_flag = cur->type_flag; - if (type_flag == (uint32_t)kProxy_flag) + if (type_flag == (uint32_t)kProxy_flag) { cur->icmp_id = pkt->identifier; + cur->ping_seq = pkt->seq; + } if (!is_pcap) cur->xfer.icmp_in++; } diff --git a/src/ptunnel.c b/src/ptunnel.c index 3f12556..640df74 100644 --- a/src/ptunnel.c +++ b/src/ptunnel.c @@ -661,12 +661,22 @@ void* pt_proxy(void *args) { if (cur->last_ack+cur->ack_interval < now && cur->send_wait_ack < cur->window_size && cur->remote_ack_val+1 != cur->next_remote_seq) { + idx = cur->send_idx; cur->last_ack = now; queue_packet(fwd_sock, cur->pkt_type, 0, 0, cur->id_no, cur->icmp_id, &cur->my_seq, cur->send_ring, &cur->send_idx, &cur->send_wait_ack, cur->dst_ip, cur->dst_port, kProto_ack | cur->type_flag, &cur->dest_addr, cur->next_remote_seq, &cur->send_first_ack, &cur->ping_seq, cur->window_size); cur->xfer.icmp_ack_out++; + if (cur->send_ring[idx].pkt_len > sizeof(icmp_echo_packet_t) && cur->send_ring[idx].pkt->type == 8) { + for (uint16_t e = 0; e < opts.empty_pings; e++) { + cur->send_ring[idx].pkt->seq = htons(cur->ping_seq); + cur->ping_seq++; + cur->send_ring[idx].pkt->checksum = htons(calc_icmp_checksum((uint16_t*)cur->send_ring[idx].pkt, sizeof(icmp_echo_packet_t))); + sendto(fwd_sock, (const void*)cur->send_ring[idx].pkt, sizeof(icmp_echo_packet_t), + 0, (struct sockaddr*)&cur->dest_addr, sizeof(struct sockaddr)); + } + } } } pthread_mutex_unlock(&chain_lock); -- cgit v1.2.3