diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-06-01 12:37:50 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-06-01 12:37:50 +0000 |
commit | 7b5c86947ee397b0dcd62ce71c992c5cd5e87971 (patch) | |
tree | f34bed207f0993d964440ffbdccb6e42f2201f4c /src | |
parent | a53a37b7011c6b75bad50ed1289a06704c7d5b4d (diff) | |
download | gnunet-7b5c86947ee397b0dcd62ce71c992c5cd5e87971.tar.gz gnunet-7b5c86947ee397b0dcd62ce71c992c5cd5e87971.zip |
-more
Diffstat (limited to 'src')
-rw-r--r-- | src/gns/gns_proxy_proto.h | 2 | ||||
-rw-r--r-- | src/gns/gnunet-gns-proxy.c | 207 |
2 files changed, 205 insertions, 4 deletions
diff --git a/src/gns/gns_proxy_proto.h b/src/gns/gns_proxy_proto.h index 85a203d7d..39f7e881c 100644 --- a/src/gns/gns_proxy_proto.h +++ b/src/gns/gns_proxy_proto.h | |||
@@ -1,4 +1,6 @@ | |||
1 | 1 | ||
2 | #define SOCKS_VERSION_5 0x05 | ||
3 | #define SOCKS_AUTH_NONE 0 | ||
2 | 4 | ||
3 | /* The socks phases */ | 5 | /* The socks phases */ |
4 | enum | 6 | enum |
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c index a2e4ee6a5..1cc889d38 100644 --- a/src/gns/gnunet-gns-proxy.c +++ b/src/gns/gnunet-gns-proxy.c | |||
@@ -21,9 +21,38 @@ | |||
21 | #include "platform.h" | 21 | #include "platform.h" |
22 | #include <gnunet_util_lib.h> | 22 | #include <gnunet_util_lib.h> |
23 | #include "gns_proxy_proto.h" | 23 | #include "gns_proxy_proto.h" |
24 | #include "gns.h" | ||
24 | 25 | ||
25 | #define GNUNET_GNS_PROXY_PORT 7777 | 26 | #define GNUNET_GNS_PROXY_PORT 7777 |
26 | 27 | ||
28 | //TODO maybe make this an api call | ||
29 | /** | ||
30 | * Checks if name is in tld | ||
31 | * | ||
32 | * @param name the name to check | ||
33 | * @param tld the TLD to check for | ||
34 | * @return GNUNET_YES or GNUNET_NO | ||
35 | */ | ||
36 | int | ||
37 | is_tld(const char* name, const char* tld) | ||
38 | { | ||
39 | int offset = 0; | ||
40 | |||
41 | if (strlen(name) <= strlen(tld)) | ||
42 | { | ||
43 | return GNUNET_NO; | ||
44 | } | ||
45 | |||
46 | offset = strlen(name)-strlen(tld); | ||
47 | if (strcmp (name+offset, tld) != 0) | ||
48 | { | ||
49 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
50 | "%s is not in .%s TLD\n", name, tld); | ||
51 | return GNUNET_NO; | ||
52 | } | ||
53 | |||
54 | return GNUNET_YES; | ||
55 | } | ||
27 | 56 | ||
28 | struct Socks5Request | 57 | struct Socks5Request |
29 | { | 58 | { |
@@ -31,10 +60,17 @@ struct Socks5Request | |||
31 | struct Socks5Request *next; | 60 | struct Socks5Request *next; |
32 | 61 | ||
33 | struct GNUNET_NETWORK_Handle *sock; | 62 | struct GNUNET_NETWORK_Handle *sock; |
63 | struct GNUNET_NETWORK_Handle *remote_sock; | ||
34 | 64 | ||
35 | int state; | 65 | int state; |
36 | 66 | ||
37 | GNUNET_SCHEDULER_TaskIdentifier rtask; | 67 | GNUNET_SCHEDULER_TaskIdentifier rtask; |
68 | GNUNET_SCHEDULER_TaskIdentifier wtask; | ||
69 | |||
70 | char rbuf[512]; | ||
71 | char wbuf[512]; | ||
72 | unsigned int rbuf_len; | ||
73 | unsigned int wbuf_len; | ||
38 | }; | 74 | }; |
39 | 75 | ||
40 | struct Socks5Connections | 76 | struct Socks5Connections |
@@ -50,6 +86,37 @@ GNUNET_SCHEDULER_TaskIdentifier ltask; | |||
50 | static struct Socks5Connections s5conns; | 86 | static struct Socks5Connections s5conns; |
51 | 87 | ||
52 | /** | 88 | /** |
89 | * Write data to socket | ||
90 | * | ||
91 | * @param cls the closure | ||
92 | * @param tc scheduler context | ||
93 | */ | ||
94 | static void | ||
95 | do_write (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
96 | { | ||
97 | struct Socks5Request *s5r = cls; | ||
98 | unsigned int len = s5r->wbuf_len; | ||
99 | |||
100 | s5r->wtask = GNUNET_SCHEDULER_NO_TASK; | ||
101 | |||
102 | if ((NULL != tc->read_ready) && | ||
103 | (GNUNET_NETWORK_fdset_isset (tc->write_ready, s5r->sock)) && | ||
104 | (len = GNUNET_NETWORK_socket_send (s5r->sock, &s5r->wbuf, | ||
105 | len))) | ||
106 | { | ||
107 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
108 | "Successfully sent %d bytes to socket\n", | ||
109 | len); | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | GNUNET_NETWORK_socket_close (s5r->sock); | ||
114 | GNUNET_free(s5r); | ||
115 | return; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /** | ||
53 | * Read data from incoming connection | 120 | * Read data from incoming connection |
54 | * | 121 | * |
55 | * @param cls the closure | 122 | * @param cls the closure |
@@ -59,14 +126,26 @@ static void | |||
59 | do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 126 | do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
60 | { | 127 | { |
61 | struct Socks5Request *s5r = cls; | 128 | struct Socks5Request *s5r = cls; |
62 | char rbuf[512]; | ||
63 | unsigned int len; | 129 | unsigned int len; |
130 | struct socks5_client_hello *c_hello; | ||
131 | struct socks5_server_hello *s_hello; | ||
132 | struct socks5_client_request *c_req; | ||
133 | struct socks5_server_response *s_resp; | ||
134 | |||
135 | char domain[256]; | ||
136 | uint8_t dom_len; | ||
137 | uint16_t req_port; | ||
138 | struct hostent *phost; | ||
139 | uint32_t remote_ip; | ||
140 | struct sockaddr_in remote_addr; | ||
141 | struct in_addr *r_sin_addr; | ||
64 | 142 | ||
65 | s5r->rtask = GNUNET_SCHEDULER_NO_TASK; | 143 | s5r->rtask = GNUNET_SCHEDULER_NO_TASK; |
66 | 144 | ||
67 | if ((NULL != tc->write_ready) && | 145 | if ((NULL != tc->write_ready) && |
68 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->sock)) && | 146 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->sock)) && |
69 | (len = GNUNET_NETWORK_socket_recv (s5r->sock, &rbuf, sizeof (rbuf)))) | 147 | (len = GNUNET_NETWORK_socket_recv (s5r->sock, &s5r->rbuf, |
148 | sizeof (s5r->rbuf)))) | ||
70 | { | 149 | { |
71 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 150 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
72 | "Successfully read %d bytes from socket\n", | 151 | "Successfully read %d bytes from socket\n", |
@@ -82,10 +161,130 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
82 | 161 | ||
83 | if (s5r->state == SOCKS5_INIT) | 162 | if (s5r->state == SOCKS5_INIT) |
84 | { | 163 | { |
85 | //DO sth etc | 164 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
165 | "SOCKS5 init\n"); | ||
166 | c_hello = (struct socks5_client_hello*)&s5r->rbuf; | ||
167 | |||
168 | GNUNET_assert (c_hello->version == SOCKS_VERSION_5); | ||
169 | |||
170 | s_hello = (struct socks5_server_hello*)&s5r->wbuf; | ||
171 | s5r->wbuf_len = sizeof( struct socks5_server_hello ); | ||
172 | |||
173 | s_hello->version = c_hello->version; | ||
174 | s_hello->auth_method = SOCKS_AUTH_NONE; | ||
175 | |||
176 | /* Write response to client */ | ||
177 | s5r->wtask = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
178 | s5r->sock, | ||
179 | &do_write, s5r); | ||
180 | |||
181 | s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
182 | s5r->sock, | ||
183 | &do_read, s5r); | ||
184 | |||
185 | s5r->state = SOCKS5_REQUEST; | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | if (s5r->state == SOCKS5_REQUEST) | ||
190 | { | ||
191 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
192 | "Processing SOCKS5 request\n"); | ||
193 | c_req = (struct socks5_client_request*)&s5r->rbuf; | ||
194 | s_resp = (struct socks5_server_response*)&s5r->wbuf; | ||
195 | s5r->wbuf_len = sizeof (struct socks5_server_response); | ||
196 | |||
197 | GNUNET_assert (c_req->addr_type == 3); | ||
198 | |||
199 | dom_len = *((uint8_t*)(&(c_req->addr_type) + 1)); | ||
200 | memset(domain, 0, sizeof(domain)); | ||
201 | strncpy(domain, (char*)(&(c_req->addr_type) + 2), dom_len); | ||
202 | req_port = *((uint16_t*)(&(c_req->addr_type) + 2 + dom_len)); | ||
203 | |||
204 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
205 | "Requested connection is %s:%d\n", | ||
206 | domain, | ||
207 | ntohs(req_port)); | ||
208 | |||
209 | if (is_tld (domain, GNUNET_GNS_TLD) || | ||
210 | is_tld (domain, GNUNET_GNS_TLD_ZKEY)) | ||
211 | { | ||
212 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
213 | "Requested connection is gnunet tld\n", | ||
214 | domain); | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | phost = (struct hostent*)gethostbyname (domain); | ||
219 | if (phost == NULL) | ||
220 | { | ||
221 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
222 | "Resolve %s error!\n", domain ); | ||
223 | s_resp->version = 0x05; | ||
224 | s_resp->reply = 0x01; | ||
225 | s5r->wtask = | ||
226 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
227 | s5r->sock, | ||
228 | &do_write, s5r); | ||
229 | //ERROR! | ||
230 | //TODO! close socket after the write! schedule task | ||
231 | //GNUNET_NETWORK_socket_close (s5r->sock); | ||
232 | //GNUNET_free(s5r); | ||
233 | return; | ||
234 | } | ||
235 | |||
236 | s5r->remote_sock = GNUNET_NETWORK_socket_create (AF_INET, | ||
237 | SOCK_STREAM, | ||
238 | 0); | ||
239 | r_sin_addr = (struct in_addr*)(phost->h_addr); | ||
240 | remote_ip = r_sin_addr->s_addr; | ||
241 | memset(&remote_addr, 0, sizeof(remote_addr)); | ||
242 | remote_addr.sin_family = AF_INET; | ||
243 | remote_addr.sin_addr.s_addr = remote_ip; | ||
244 | remote_addr.sin_port = req_port; | ||
245 | |||
246 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
247 | "target server: %s:%u\n", inet_ntoa(remote_addr.sin_addr), | ||
248 | ntohs(req_port)); | ||
249 | |||
250 | GNUNET_assert ( s5r->remote_sock != NULL ); | ||
251 | |||
252 | if (GNUNET_OK != | ||
253 | GNUNET_NETWORK_socket_connect ( s5r->remote_sock, | ||
254 | (struct sockaddr*)&remote_addr, | ||
255 | sizeof (struct sockaddr))) | ||
256 | { | ||
257 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
258 | "socket request error...\n"); | ||
259 | s_resp->version = 0x05; | ||
260 | s_resp->reply = 0x01; | ||
261 | s5r->wtask = | ||
262 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
263 | s5r->sock, | ||
264 | &do_write, s5r); | ||
265 | //TODO see above | ||
266 | return; | ||
267 | } | ||
268 | |||
269 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
270 | "new remote connection\n"); | ||
271 | |||
272 | s_resp->version = 0x05; | ||
273 | s_resp->reply = 0x00; | ||
274 | s_resp->reserved = 0x00; | ||
275 | s_resp->addr_type = 0x01; | ||
276 | |||
277 | s5r->state = SOCKS5_DATA_TRANSFER; | ||
278 | |||
279 | s5r->wtask = | ||
280 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
281 | s5r->sock, | ||
282 | &do_write, s5r); | ||
283 | |||
284 | } | ||
86 | } | 285 | } |
87 | 286 | ||
88 | GNUNET_CONTAINER_DLL_remove (s5conns.head, s5conns.tail, s5r); | 287 | //GNUNET_CONTAINER_DLL_remove (s5conns.head, s5conns.tail, s5r); |
89 | 288 | ||
90 | } | 289 | } |
91 | 290 | ||