aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pdesc.c120
-rw-r--r--pdesc.h10
-rw-r--r--pkt.c159
-rw-r--r--pkt.h10
-rw-r--r--ptunnel.c279
-rw-r--r--ptunnel.h14
6 files changed, 297 insertions, 295 deletions
diff --git a/pdesc.c b/pdesc.c
index 24f2173..44e18ee 100644
--- a/pdesc.c
+++ b/pdesc.c
@@ -115,6 +115,126 @@ forward_desc_t* create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data)
return fwd_desc;
}
+/* queue_packet:
+ * Creates an ICMP packet descriptor, and sends it. The packet descriptor is added
+ * to the given send ring, for potential resends later on.
+ */
+int queue_packet(int icmp_sock, uint8_t type, char *buf, int num_bytes,
+ uint16_t id_no, uint16_t icmp_id, uint16_t *seq, icmp_desc_t ring[],
+ int *insert_idx, int *await_send, uint32_t ip, uint32_t port,
+ uint32_t state, struct sockaddr_in *dest_addr, uint16_t next_expected_seq,
+ int *first_ack, uint16_t *ping_seq)
+{
+#if kPT_add_iphdr
+ ip_packet_t *ip_pkt = 0;
+ int pkt_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) +
+ sizeof(ping_tunnel_pkt_t) + num_bytes;
+#else
+ int pkt_len = sizeof(icmp_echo_packet_t) +
+ sizeof(ping_tunnel_pkt_t) + num_bytes;
+#endif
+ int err = 0;
+ icmp_echo_packet_t *pkt = 0;
+ ping_tunnel_pkt_t *pt_pkt = 0;
+ uint16_t ack_val = next_expected_seq - 1;
+
+ if (pkt_len % 2)
+ pkt_len++;
+
+#if kPT_add_iphdr
+ printf("add header\n");
+ ip_pkt = (ip_packet_t *) malloc(pkt_len);
+ pkt = (icmp_echo_packet_t *) ip_pkt->data;
+ memset(ip_pkt, 0, sizeof(ip_packet_t));
+ /* |(pkt_len>>2);//5;//(IPVERSION << 4) | (sizeof(ip_packet_t) >> 2); */
+ ip_pkt->vers_ihl = 0x45;
+ ip_pkt->tos = IPTOS_LOWDELAY;
+ ip_pkt->pkt_len = pkt_len;
+ /* kernel sets proper value htons(ip_id_counter); */
+ ip_pkt->id = 0;
+ ip_pkt->flags_frag_offset = 0;
+ /* default time to live (64) */
+ ip_pkt->ttl = IPDEFTTL;
+ /* ICMP */
+ ip_pkt->proto = 1;
+ /* maybe the kernel helps us out..? */
+ ip_pkt->checksum = 0;
+ /* insert source IP address here */
+ ip_pkt->src_ip = htonl(0x0);
+ /* htonl(0x7f000001); -> localhost.. */
+ ip_pkt->dst_ip = dest_addr->sin_addr.s_addr;
+#else
+ pkt = (icmp_echo_packet_t *) calloc(1, pkt_len);
+#endif
+
+ /* ICMP Echo request or reply */
+ pkt->type = type;
+ /* Must be zero (non-zero requires root) */
+ pkt->code = 0;
+ pkt->identifier = htons(icmp_id);
+ pkt->seq = htons(*ping_seq);
+ pkt->checksum = 0;
+ (*ping_seq)++;
+ /* Add our information */
+ pt_pkt = (ping_tunnel_pkt_t*)pkt->data;
+ pt_pkt->magic = htonl(opts.magic);
+ pt_pkt->dst_ip = ip;
+ pt_pkt->dst_port = htonl(port);
+ pt_pkt->ack = htonl(ack_val);
+ pt_pkt->data_len = htonl(num_bytes);
+ pt_pkt->state = htonl(state);
+ pt_pkt->seq_no = htons(*seq);
+ pt_pkt->id_no = htons(id_no);
+ /* Copy user data */
+ if (buf && num_bytes > 0)
+ memcpy(pt_pkt->data, buf, num_bytes);
+#if kPT_add_iphdr
+ pkt->checksum = htons(calc_icmp_checksum((uint16_t*)pkt, pkt_len-sizeof(ip_packet_t)));
+ ip_pkt->checksum = htons(calc_icmp_checksum((uint16_t*)ip_pkt, sizeof(ip_packet_t)));
+#else
+ pkt->checksum = htons(calc_icmp_checksum((uint16_t*)pkt, pkt_len));
+#endif
+
+ /* Send it! */
+ pt_log(kLog_sendrecv, "Send: %d [%d] bytes [seq = %d] "
+ "[type = %s] [ack = %d] [icmp = %d] [user = %s]\n",
+ pkt_len, num_bytes, *seq, state_name[state & (~kFlag_mask)],
+ ack_val, type, ((state & kUser_flag) == kUser_flag ? "yes" : "no"));
+#if kPT_add_iphdr
+ err = sendto(icmp_sock, (const void*)ip_pkt, pkt_len, 0,
+ (struct sockaddr*)dest_addr, sizeof(struct sockaddr));
+#else
+ err = sendto(icmp_sock, (const void*)pkt, pkt_len, 0,
+ (struct sockaddr*)dest_addr, sizeof(struct sockaddr));
+#endif
+ if (err < 0) {
+ pt_log(kLog_error, "Failed to send ICMP packet: %s\n", strerror(errno));
+ return -1;
+ }
+ else if (err != pkt_len)
+ pt_log(kLog_error, "WARNING WARNING, didn't send entire packet\n");
+
+ /* Update sequence no's and so on */
+#if kPT_add_iphdr
+ /* NOTE: Retry mechanism needs update for PT_add_ip_hdr */
+ ring[*insert_idx].pkt = ip_pkt;
+#else
+ ring[*insert_idx].pkt = pkt;
+#endif
+ ring[*insert_idx].pkt_len = pkt_len;
+ ring[*insert_idx].last_resend = time_as_double();
+ ring[*insert_idx].seq_no = *seq;
+ ring[*insert_idx].icmp_id = icmp_id;
+ (*seq)++;
+ if (!ring[*first_ack].pkt)
+ *first_ack = *insert_idx;
+ (*await_send)++;
+ (*insert_idx)++;
+ if (*insert_idx >= kPing_window_size)
+ *insert_idx = 0;
+ return 0;
+}
+
/* send_packets:
* Examines the passed-in ring, and forwards data in it over TCP.
*/
diff --git a/pdesc.h b/pdesc.h
index f486062..18751b7 100644
--- a/pdesc.h
+++ b/pdesc.h
@@ -24,7 +24,7 @@
* The same procedure is followed in proxy-to-client communication. Just replace
* proxy with client and vice versa in the list above.
*/
-typedef struct {
+typedef struct forward_desc_t {
/** ping_tunnel_pkt_t seq_no */
int seq_no;
/** length of data */
@@ -40,7 +40,7 @@ typedef struct {
* it will be removed from the send-ring, freeing up space for more outgoing
* ICMP packets.
*/
-typedef struct {
+typedef struct icmp_desc_t {
/** total length of ICMP packet, including ICMP header and ptunnel data. */
int pkt_len;
double last_resend;
@@ -125,6 +125,12 @@ void remove_proxy_desc(proxy_desc_t *cur, proxy_desc_t *prev);
forward_desc_t* create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data);
+int queue_packet(int icmp_sock, uint8_t type, char *buf, int num_bytes,
+ uint16_t id_no, uint16_t icmp_id, uint16_t *seq, icmp_desc_t ring[],
+ int *insert_idx, int *await_send, uint32_t ip, uint32_t port,
+ uint32_t state, struct sockaddr_in *dest_addr, uint16_t next_expected_seq,
+ int *first_ack, uint16_t *ping_seq);
+
uint32_t send_packets(forward_desc_t *ring[], int *xfer_idx, int *await_send, int *sock);
#endif
diff --git a/pkt.c b/pkt.c
index 07388c4..9bd8777 100644
--- a/pkt.c
+++ b/pkt.c
@@ -242,3 +242,162 @@ void handle_packet(char *buf, unsigned bytes, int is_pcap, struct sockaddr_in *a
pt_log(kLog_verbose, "Ignored incoming packet.\n");
}
}
+
+/* handle_data:
+ * Utility function for handling kProto_data packets, and place the data it contains
+ * onto the passed-in receive ring.
+ */
+void handle_data(icmp_echo_packet_t *pkt, int total_len, forward_desc_t *ring[],
+ int *await_send, int *insert_idx, uint16_t *next_expected_seq)
+{
+ ping_tunnel_pkt_t *pt_pkt = (ping_tunnel_pkt_t*)pkt->data;
+ int expected_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) +
+ sizeof(ping_tunnel_pkt_t); /* 20+8+28 */
+ /* Place packet in the receive ring, in its proper place.
+ * This works as follows:
+ * -1. Packet == ack packet? Perform ack, and continue.
+ * 0. seq_no < next_remote_seq, and absolute difference is bigger than w size => discard
+ * 1. If seq_no == next_remote_seq, we have no problems; just put it in the ring.
+ * 2. If seq_no > next_remote_seq + remaining window size, discard packet.
+ * Send resend request for missing packets.
+ * 3. Else, put packet in the proper place in the ring
+ * (don't overwrite if one is already there), but don't increment next_remote_seq_no
+ * 4. If packed was not discarded, process ack info in packet.
+ */
+ expected_len += pt_pkt->data_len;
+ expected_len += expected_len % 2;
+ if (opts.udp)
+ expected_len -= sizeof(ip_packet_t);
+ if (total_len < expected_len) {
+ pt_log(kLog_error, "Packet not completely received: %d Should be: %d. "
+ "For some reason, this error is fatal.\n", total_len, expected_len);
+ pt_log(kLog_debug, "Data length: %d Total length: %d\n", pt_pkt->data_len, total_len);
+ /* TODO: This error isn't fatal, so it should definitely be handled in some way.
+ * We could simply discard it.
+ */
+ exit(0);
+ }
+ if (pt_pkt->seq_no == *next_expected_seq) {
+ /* hmm, what happens if this test is true? */
+ if (!ring[*insert_idx]) { /* && pt_pkt->state == kProto_data */
+ /* pt_log(kLog_debug, "Queing data packet: %d\n", pt_pkt->seq_no); */
+ ring[*insert_idx] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data);
+ (*await_send)++;
+ (*insert_idx)++;
+ }
+ else if (ring[*insert_idx])
+ pt_log(kLog_debug, "Dup packet?\n");
+
+ (*next_expected_seq)++;
+ if (*insert_idx >= kPing_window_size)
+ *insert_idx = 0;
+ /* Check if we have already received some of the next packets */
+ while (ring[*insert_idx]) {
+ if (ring[*insert_idx]->seq_no == *next_expected_seq) {
+ (*next_expected_seq)++;
+ (*insert_idx)++;
+ if (*insert_idx >= kPing_window_size)
+ *insert_idx = 0;
+ }
+ else
+ break;
+ }
+ }
+ else {
+ int r, s, d, pos;
+ pos = -1; /* If pos ends up staying -1, packet is discarded. */
+ r = *next_expected_seq;
+ s = pt_pkt->seq_no;
+ d = s - r;
+ if (d < 0) { /* This packet _may_ be old, or seq_no may have wrapped around */
+ d = (s+0xFFFF) - r;
+ if (d < kPing_window_size) {
+ /* Counter has wrapped, so we should add this packet to the recv ring */
+ pos = ((*insert_idx)+d) % kPing_window_size;
+ }
+ }
+ else if (d < kPing_window_size)
+ pos = ((*insert_idx)+d) % kPing_window_size;
+
+ if (pos != -1) {
+ if (!ring[pos]) {
+ pt_log(kLog_verbose, "Out of order. Expected: %d Got: %d Inserted: %d "
+ "(cur = %d)\n", *next_expected_seq, pt_pkt->seq_no, pos,
+ (*insert_idx));
+ ring[pos] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data);
+ (*await_send)++;
+ }
+ }
+ /* else
+ * pt_log(kLog_debug, "Packet discarded - outside receive window.\n");
+ */
+ }
+}
+
+void handle_ack(uint16_t seq_no, icmp_desc_t ring[], int *packets_awaiting_ack,
+ int one_ack_only, int insert_idx, int *first_ack,
+ uint16_t *remote_ack, int is_pcap)
+{
+ int i, j, k;
+ ping_tunnel_pkt_t *pt_pkt;
+
+ if (*packets_awaiting_ack > 0) {
+ if (one_ack_only) {
+ for (i = 0; i < kPing_window_size; i++) {
+ if (ring[i].pkt && ring[i].seq_no == seq_no && !is_pcap) {
+ pt_log(kLog_debug, "Received ack for only seq %d\n", seq_no);
+ pt_pkt = (ping_tunnel_pkt_t*)ring[i].pkt->data;
+ /* WARNING: We make the dangerous assumption here that packets arrive in order! */
+ *remote_ack = (uint16_t)ntohl(pt_pkt->ack);
+ free(ring[i].pkt);
+ ring[i].pkt = 0;
+ (*packets_awaiting_ack)--;
+ if (i == *first_ack) {
+ for (j=1;j<kPing_window_size;j++) {
+ k = (i+j)%kPing_window_size;
+ if (ring[k].pkt) {
+ *first_ack = k;
+ break;
+ }
+ /* we have looped through everything */
+ if (k == i)
+ *first_ack = insert_idx;
+ j++;
+ }
+ }
+ return;
+ }
+ }
+ }
+ else {
+ int i, can_ack = 0, count = 0;
+ i = insert_idx-1;
+ if (i < 0)
+ i = kPing_window_size - 1;
+
+ pt_log(kLog_debug, "Received ack-series starting at seq %d\n", seq_no);
+ while (count < kPing_window_size) {
+ if (!ring[i].pkt)
+ break;
+
+ if (ring[i].seq_no == seq_no)
+ can_ack = 1;
+ else if (!can_ack)
+ *first_ack = i;
+
+ if (can_ack) {
+ free(ring[i].pkt);
+ ring[i].pkt = 0;
+ (*packets_awaiting_ack)--;
+ }
+ i--;
+ if (i < 0)
+ i = kPing_window_size - 1;
+ count++;
+ }
+ }
+ }
+/* else
+ * pt_log(kLog_verbose, "Dropping superfluous acknowledgement (no outstanding packets needing ack.)\n");
+ */
+}
diff --git a/pkt.h b/pkt.h
index c3731cb..22c039d 100644
--- a/pkt.h
+++ b/pkt.h
@@ -80,7 +80,17 @@ typedef struct {
char data[0];
} __attribute__ ((packed)) icmp_echo_packet_t;
+typedef struct forward_desc_t forward_desc_t;
+typedef struct icmp_desc_t icmp_desc_t;
+
void handle_packet(char *buf, unsigned bytes, int is_pcap, struct sockaddr_in *addr, int icmp_sock);
+void handle_data(icmp_echo_packet_t *pkt, int total_len, forward_desc_t **ring,
+ int *await_send, int *insert_idx, uint16_t *next_expected_seq);
+
+void handle_ack(uint16_t seq_no, icmp_desc_t *ring, int *packets_awaiting_ack,
+ int one_ack_only, int insert_idx, int *first_ack,
+ uint16_t *remote_ack, int is_pcap);
+
#endif
diff --git a/ptunnel.c b/ptunnel.c
index c672a04..b2ab310 100644
--- a/ptunnel.c
+++ b/ptunnel.c
@@ -754,285 +754,6 @@ void pcap_packet_handler(u_char *refcon, const struct pcap_pkthdr *hdr, const u_
static int ip_id_counter = 1;
#endif
-/* queue_packet:
- * Creates an ICMP packet descriptor, and sends it. The packet descriptor is added
- * to the given send ring, for potential resends later on.
- */
-int queue_packet(int icmp_sock, uint8_t type, char *buf, int num_bytes,
- uint16_t id_no, uint16_t icmp_id, uint16_t *seq, icmp_desc_t ring[],
- int *insert_idx, int *await_send, uint32_t ip, uint32_t port,
- uint32_t state, struct sockaddr_in *dest_addr, uint16_t next_expected_seq,
- int *first_ack, uint16_t *ping_seq)
-{
-#if kPT_add_iphdr
- ip_packet_t *ip_pkt = 0;
- int pkt_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) +
- sizeof(ping_tunnel_pkt_t) + num_bytes;
-#else
- int pkt_len = sizeof(icmp_echo_packet_t) +
- sizeof(ping_tunnel_pkt_t) + num_bytes;
-#endif
- int err = 0;
- icmp_echo_packet_t *pkt = 0;
- ping_tunnel_pkt_t *pt_pkt = 0;
- uint16_t ack_val = next_expected_seq - 1;
-
- if (pkt_len % 2)
- pkt_len++;
-
-#if kPT_add_iphdr
- printf("add header\n");
- ip_pkt = (ip_packet_t *) malloc(pkt_len);
- pkt = (icmp_echo_packet_t *) ip_pkt->data;
- memset(ip_pkt, 0, sizeof(ip_packet_t));
- /* |(pkt_len>>2);//5;//(IPVERSION << 4) | (sizeof(ip_packet_t) >> 2); */
- ip_pkt->vers_ihl = 0x45;
- ip_pkt->tos = IPTOS_LOWDELAY;
- ip_pkt->pkt_len = pkt_len;
- /* kernel sets proper value htons(ip_id_counter); */
- ip_pkt->id = 0;
- ip_pkt->flags_frag_offset = 0;
- /* default time to live (64) */
- ip_pkt->ttl = IPDEFTTL;
- /* ICMP */
- ip_pkt->proto = 1;
- /* maybe the kernel helps us out..? */
- ip_pkt->checksum = 0;
- /* insert source IP address here */
- ip_pkt->src_ip = htonl(0x0);
- /* htonl(0x7f000001); -> localhost.. */
- ip_pkt->dst_ip = dest_addr->sin_addr.s_addr;
-#else
- pkt = (icmp_echo_packet_t *) calloc(1, pkt_len);
-#endif
-
- /* ICMP Echo request or reply */
- pkt->type = type;
- /* Must be zero (non-zero requires root) */
- pkt->code = 0;
- pkt->identifier = htons(icmp_id);
- pkt->seq = htons(*ping_seq);
- pkt->checksum = 0;
- (*ping_seq)++;
- /* Add our information */
- pt_pkt = (ping_tunnel_pkt_t*)pkt->data;
- pt_pkt->magic = htonl(opts.magic);
- pt_pkt->dst_ip = ip;
- pt_pkt->dst_port = htonl(port);
- pt_pkt->ack = htonl(ack_val);
- pt_pkt->data_len = htonl(num_bytes);
- pt_pkt->state = htonl(state);
- pt_pkt->seq_no = htons(*seq);
- pt_pkt->id_no = htons(id_no);
- /* Copy user data */
- if (buf && num_bytes > 0)
- memcpy(pt_pkt->data, buf, num_bytes);
-#if kPT_add_iphdr
- pkt->checksum = htons(calc_icmp_checksum((uint16_t*)pkt, pkt_len-sizeof(ip_packet_t)));
- ip_pkt->checksum = htons(calc_icmp_checksum((uint16_t*)ip_pkt, sizeof(ip_packet_t)));
-#else
- pkt->checksum = htons(calc_icmp_checksum((uint16_t*)pkt, pkt_len));
-#endif
-
- /* Send it! */
- pt_log(kLog_sendrecv, "Send: %d [%d] bytes [seq = %d] "
- "[type = %s] [ack = %d] [icmp = %d] [user = %s]\n",
- pkt_len, num_bytes, *seq, state_name[state & (~kFlag_mask)],
- ack_val, type, ((state & kUser_flag) == kUser_flag ? "yes" : "no"));
-#if kPT_add_iphdr
- err = sendto(icmp_sock, (const void*)ip_pkt, pkt_len, 0,
- (struct sockaddr*)dest_addr, sizeof(struct sockaddr));
-#else
- err = sendto(icmp_sock, (const void*)pkt, pkt_len, 0,
- (struct sockaddr*)dest_addr, sizeof(struct sockaddr));
-#endif
- if (err < 0) {
- pt_log(kLog_error, "Failed to send ICMP packet: %s\n", strerror(errno));
- return -1;
- }
- else if (err != pkt_len)
- pt_log(kLog_error, "WARNING WARNING, didn't send entire packet\n");
-
- /* Update sequence no's and so on */
-#if kPT_add_iphdr
- /* NOTE: Retry mechanism needs update for PT_add_ip_hdr */
- ring[*insert_idx].pkt = ip_pkt;
-#else
- ring[*insert_idx].pkt = pkt;
-#endif
- ring[*insert_idx].pkt_len = pkt_len;
- ring[*insert_idx].last_resend = time_as_double();
- ring[*insert_idx].seq_no = *seq;
- ring[*insert_idx].icmp_id = icmp_id;
- (*seq)++;
- if (!ring[*first_ack].pkt)
- *first_ack = *insert_idx;
- (*await_send)++;
- (*insert_idx)++;
- if (*insert_idx >= kPing_window_size)
- *insert_idx = 0;
- return 0;
-}
-
-/* handle_data:
- * Utility function for handling kProto_data packets, and place the data it contains
- * onto the passed-in receive ring.
- */
-void handle_data(icmp_echo_packet_t *pkt, int total_len, forward_desc_t *ring[],
- int *await_send, int *insert_idx, uint16_t *next_expected_seq)
-{
- ping_tunnel_pkt_t *pt_pkt = (ping_tunnel_pkt_t*)pkt->data;
- int expected_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) +
- sizeof(ping_tunnel_pkt_t); /* 20+8+28 */
- /* Place packet in the receive ring, in its proper place.
- * This works as follows:
- * -1. Packet == ack packet? Perform ack, and continue.
- * 0. seq_no < next_remote_seq, and absolute difference is bigger than w size => discard
- * 1. If seq_no == next_remote_seq, we have no problems; just put it in the ring.
- * 2. If seq_no > next_remote_seq + remaining window size, discard packet.
- * Send resend request for missing packets.
- * 3. Else, put packet in the proper place in the ring
- * (don't overwrite if one is already there), but don't increment next_remote_seq_no
- * 4. If packed was not discarded, process ack info in packet.
- */
- expected_len += pt_pkt->data_len;
- expected_len += expected_len % 2;
- if (opts.udp)
- expected_len -= sizeof(ip_packet_t);
- if (total_len < expected_len) {
- pt_log(kLog_error, "Packet not completely received: %d Should be: %d. "
- "For some reason, this error is fatal.\n", total_len, expected_len);
- pt_log(kLog_debug, "Data length: %d Total length: %d\n", pt_pkt->data_len, total_len);
- /* TODO: This error isn't fatal, so it should definitely be handled in some way.
- * We could simply discard it.
- */
- exit(0);
- }
- if (pt_pkt->seq_no == *next_expected_seq) {
- /* hmm, what happens if this test is true? */
- if (!ring[*insert_idx]) { /* && pt_pkt->state == kProto_data */
- /* pt_log(kLog_debug, "Queing data packet: %d\n", pt_pkt->seq_no); */
- ring[*insert_idx] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data);
- (*await_send)++;
- (*insert_idx)++;
- }
- else if (ring[*insert_idx])
- pt_log(kLog_debug, "Dup packet?\n");
-
- (*next_expected_seq)++;
- if (*insert_idx >= kPing_window_size)
- *insert_idx = 0;
- /* Check if we have already received some of the next packets */
- while (ring[*insert_idx]) {
- if (ring[*insert_idx]->seq_no == *next_expected_seq) {
- (*next_expected_seq)++;
- (*insert_idx)++;
- if (*insert_idx >= kPing_window_size)
- *insert_idx = 0;
- }
- else
- break;
- }
- }
- else {
- int r, s, d, pos;
- pos = -1; /* If pos ends up staying -1, packet is discarded. */
- r = *next_expected_seq;
- s = pt_pkt->seq_no;
- d = s - r;
- if (d < 0) { /* This packet _may_ be old, or seq_no may have wrapped around */
- d = (s+0xFFFF) - r;
- if (d < kPing_window_size) {
- /* Counter has wrapped, so we should add this packet to the recv ring */
- pos = ((*insert_idx)+d) % kPing_window_size;
- }
- }
- else if (d < kPing_window_size)
- pos = ((*insert_idx)+d) % kPing_window_size;
-
- if (pos != -1) {
- if (!ring[pos]) {
- pt_log(kLog_verbose, "Out of order. Expected: %d Got: %d Inserted: %d "
- "(cur = %d)\n", *next_expected_seq, pt_pkt->seq_no, pos,
- (*insert_idx));
- ring[pos] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data);
- (*await_send)++;
- }
- }
- /* else
- * pt_log(kLog_debug, "Packet discarded - outside receive window.\n");
- */
- }
-}
-
-void handle_ack(uint16_t seq_no, icmp_desc_t ring[], int *packets_awaiting_ack,
- int one_ack_only, int insert_idx, int *first_ack,
- uint16_t *remote_ack, int is_pcap)
-{
- int i, j, k;
- ping_tunnel_pkt_t *pt_pkt;
-
- if (*packets_awaiting_ack > 0) {
- if (one_ack_only) {
- for (i = 0; i < kPing_window_size; i++) {
- if (ring[i].pkt && ring[i].seq_no == seq_no && !is_pcap) {
- pt_log(kLog_debug, "Received ack for only seq %d\n", seq_no);
- pt_pkt = (ping_tunnel_pkt_t*)ring[i].pkt->data;
- /* WARNING: We make the dangerous assumption here that packets arrive in order! */
- *remote_ack = (uint16_t)ntohl(pt_pkt->ack);
- free(ring[i].pkt);
- ring[i].pkt = 0;
- (*packets_awaiting_ack)--;
- if (i == *first_ack) {
- for (j=1;j<kPing_window_size;j++) {
- k = (i+j)%kPing_window_size;
- if (ring[k].pkt) {
- *first_ack = k;
- break;
- }
- /* we have looped through everything */
- if (k == i)
- *first_ack = insert_idx;
- j++;
- }
- }
- return;
- }
- }
- }
- else {
- int i, can_ack = 0, count = 0;
- i = insert_idx-1;
- if (i < 0)
- i = kPing_window_size - 1;
-
- pt_log(kLog_debug, "Received ack-series starting at seq %d\n", seq_no);
- while (count < kPing_window_size) {
- if (!ring[i].pkt)
- break;
-
- if (ring[i].seq_no == seq_no)
- can_ack = 1;
- else if (!can_ack)
- *first_ack = i;
-
- if (can_ack) {
- free(ring[i].pkt);
- ring[i].pkt = 0;
- (*packets_awaiting_ack)--;
- }
- i--;
- if (i < 0)
- i = kPing_window_size - 1;
- count++;
- }
- }
- }
-/* else
- * pt_log(kLog_verbose, "Dropping superfluous acknowledgement (no outstanding packets needing ack.)\n");
- */
-}
-
uint16_t calc_icmp_checksum(uint16_t *data, int bytes) {
uint32_t sum;
int i;
diff --git a/ptunnel.h b/ptunnel.h
index d0714e3..e1afc33 100644
--- a/ptunnel.h
+++ b/ptunnel.h
@@ -133,24 +133,10 @@ void pt_forwarder(void);
void print_statistics(xfer_stats_t *xfer, int is_continuous);
-int queue_packet(int icmp_sock, uint8_t type, char *buf, int num_bytes,
- uint16_t id_no, uint16_t icmp_id, uint16_t *seq, icmp_desc_t ring[],
- int *insert_idx, int *await_send, uint32_t ip, uint32_t port,
- uint32_t state, struct sockaddr_in *dest_addr, uint16_t next_expected_seq,
- int *first_ack, uint16_t *ping_seq);
-
-void handle_data(icmp_echo_packet_t *pkt, int total_len, forward_desc_t *ring[],
- int *await_send, int *insert_idx, uint16_t *next_expected_seq);
-
-void handle_ack(uint16_t seq_no, icmp_desc_t ring[], int *packets_awaiting_ack,
- int one_ack_only, int insert_idx, int *first_ack, uint16_t *remote_ack,
- int is_pcap);
-
void init_ip_packet(ip_packet_t *packet, uint16_t id, uint16_t frag_offset,
uint16_t pkt_len, uint8_t ttl, uint32_t src_ip, uint32_t dst_ip,
bool is_last_frag, bool dont_frag);
-uint16_t calc_ip_checksum(ip_packet_t *pkt);
uint16_t calc_icmp_checksum(uint16_t *data, int bytes);
void send_termination_msg(proxy_desc_t *cur, int icmp_sock);