1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#include <stdlib.h>
#include "pdesc.h"
#include "options.h"
#include "utils.h"
#include "ptunnel.h"
/* create_and_insert_proxy_desc: Creates a new proxy descriptor, linking it into
* the descriptor chain. If the sock argument is 0, the function will establish
* a TCP connection to the ip and port given by dst_ip, dst_port.
*/
proxy_desc_t* create_and_insert_proxy_desc(uint16_t id_no, uint16_t icmp_id,
int sock, struct sockaddr_in *addr,
uint32_t dst_ip, uint32_t dst_port,
uint32_t init_state, uint32_t type) {
proxy_desc_t *cur;
pthread_mutex_lock(&chain_lock);
if (num_tunnels >= opts.max_tunnels) {
pt_log(kLog_info, "Discarding incoming connection - too many tunnels! Maximum count is %u (adjust with the -m switch).\n", opts.max_tunnels);
if (sock)
close(sock);
pthread_mutex_unlock(&chain_lock);
return 0;
}
num_tunnels++;
pthread_mutex_unlock(&chain_lock);
pt_log(kLog_debug, "Adding proxy desc to run loop. Type is %s. Will create socket: %s\n", (type == kUser_flag ? "user" : "proxy"), (sock ? "No" : "Yes"));
cur = (proxy_desc_t *) calloc(1, sizeof(proxy_desc_t));
cur->id_no = id_no;
cur->dest_addr = *addr;
cur->dst_ip = dst_ip;
cur->dst_port = dst_port;
cur->icmp_id = icmp_id;
if (!sock) {
cur->sock = socket(AF_INET, SOCK_STREAM, 0);
memset(addr, 0, sizeof(struct sockaddr_in));
addr->sin_port = htons((uint16_t)dst_port);
addr->sin_addr.s_addr = dst_ip;
addr->sin_family = AF_INET;
/* Let's just assume success, shall we? */
if (connect(cur->sock, (struct sockaddr*)addr, sizeof(struct sockaddr_in)) < 0) {
pt_log(kLog_error, "Connect to %s:%d failed: %s\n", inet_ntoa(*(struct in_addr*)&addr->sin_addr.s_addr) , ntohs(addr->sin_port), strerror(errno));
}
}
else
cur->sock = sock;
cur->state = init_state;
cur->type_flag = type;
if (cur->type_flag == kUser_flag)
cur->pkt_type = kICMP_echo_request;
else
cur->pkt_type = (opts.unprivileged ? kICMP_echo_request : kICMP_echo_reply);
cur->buf = (char *) malloc(icmp_receive_buf_len);
cur->last_activity = time_as_double();
cur->authenticated = 0;
pthread_mutex_lock(&chain_lock);
cur->next = chain;
chain = cur;
pthread_mutex_unlock(&chain_lock);
cur->xfer.bytes_in = 0.0;
cur->xfer.bytes_out = 0.0;
return cur;
}
/* remove_proxy_desc: Removes the given proxy desc, freeing its resources.
* Assumes that we hold the chain_lock.
*/
void remove_proxy_desc(proxy_desc_t *cur, proxy_desc_t *prev) {
int i;
struct timeval tt;
pt_log(kLog_debug, "Removing proxy descriptor.\n");
/* Get a timestamp, for making an entry in the seq_expiry_tbl */
gettimeofday(&tt, 0);
seq_expiry_tbl[cur->id_no] = tt.tv_sec+(2*kAutomatic_close_timeout);
/* Free resources associated with connection */
if (cur->buf)
free(cur->buf);
cur->buf = 0;
for (i=0;i<kPing_window_size;i++) {
if (cur->send_ring[i].pkt)
free(cur->send_ring[i].pkt);
cur->send_ring[i].pkt = 0;
if (cur->recv_ring[i])
free(cur->recv_ring[i]);
cur->recv_ring[i] = 0;
}
close(cur->sock);
cur->sock = 0;
/* Keep list up-to-date */
if (prev)
prev->next = cur->next;
else
chain = cur->next;
if (cur->challenge)
free(cur->challenge);
free(cur);
num_tunnels--;
}
forward_desc_t* create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data) {
forward_desc_t *fwd_desc;
fwd_desc = (forward_desc_t *) malloc(sizeof(forward_desc_t)+data_len);
fwd_desc->seq_no = seq_no;
fwd_desc->length = data_len;
fwd_desc->remaining = data_len;
if (data_len > 0)
memcpy(fwd_desc->data, data, data_len);
return fwd_desc;
}
|