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