00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "libts.h"
00031 #include "StatSystem.h"
00032 #include "P_Net.h"
00033 #include "I_OneWayTunnel.h"
00034 #include "HttpSessionAccept.h"
00035
00036 enum
00037 {
00038 socksproxy_http_connections_stat,
00039 socksproxy_tunneled_connections_stat,
00040
00041 socksproxy_stat_count
00042 };
00043 static RecRawStatBlock *socksproxy_stat_block;
00044
00045 #define SOCKSPROXY_INC_STAT(x) \
00046 RecIncrRawStat(socksproxy_stat_block, mutex->thread_holding, x)
00047
00048 struct SocksProxy: public Continuation
00049 {
00050 typedef int (SocksProxy::*EventHandler) (int event, void *data);
00051
00052 enum
00053 { SOCKS_INIT = 1, SOCKS_ACCEPT, AUTH_DONE, SERVER_TUNNEL,
00054 HTTP_REQ, RESP_TO_CLIENT, ALL_DONE, SOCKS_ERROR
00055 };
00056
00057 SocksProxy()
00058 : Continuation(),
00059 clientVC(0), clientVIO(0), buf(0), timeout(0),
00060 auth_handler(0), version(0), state(SOCKS_INIT), recursion(0), pending_action(NULL)
00061 {
00062 }
00063 ~SocksProxy()
00064 {
00065 }
00066
00067
00068
00069 int mainEvent(int event, void *data);
00070 int setupHttpRequest(unsigned char *p);
00071
00072
00073 int sendResp(bool granted);
00074
00075 void init(NetVConnection * netVC);
00076 void free();
00077
00078 private:
00079
00080 NetVConnection * clientVC;
00081 VIO *clientVIO;
00082
00083 MIOBuffer *buf;
00084 IOBufferReader *reader;
00085 Event *timeout;
00086
00087 SocksAuthHandler auth_handler;
00088
00089 unsigned char version;
00090
00091 int state;
00092 int recursion;
00093 Action *pending_action;
00094 };
00095
00096 ClassAllocator<SocksProxy> socksProxyAllocator("socksProxyAllocator");
00097
00098 void
00099 SocksProxy::init(NetVConnection * netVC)
00100 {
00101 mutex = new_ProxyMutex();
00102 buf = new_MIOBuffer();
00103 reader = buf->alloc_reader();
00104
00105 MUTEX_LOCK(lock, mutex, this_ethread());
00106
00107 SET_HANDLER((EventHandler) & SocksProxy::mainEvent);
00108
00109 mainEvent(NET_EVENT_ACCEPT, netVC);
00110 }
00111
00112 void
00113 SocksProxy::free()
00114 {
00115 if (buf)
00116 free_MIOBuffer(buf);
00117
00118 mutex = NULL;
00119
00120 socksProxyAllocator.free(this);
00121 }
00122
00123 int
00124 SocksProxy::mainEvent(int event, void *data)
00125 {
00126 int ret = EVENT_DONE;
00127 unsigned char *p;
00128
00129 VIO *vio;
00130 int64_t n_read_avail;
00131
00132
00133 recursion++;
00134
00135 switch (event) {
00136
00137 case NET_EVENT_ACCEPT:
00138 state = SOCKS_ACCEPT;
00139 Debug("SocksProxy", "Proxy got accept event\n");
00140
00141 clientVC = (NetVConnection *) data;
00142 clientVC->socks_addr.reset();
00143
00144 case VC_EVENT_WRITE_COMPLETE:
00145
00146 switch (state) {
00147 case HTTP_REQ:{
00148 HttpSessionAccept::Options ha_opt;
00149
00150
00151 SOCKSPROXY_INC_STAT(socksproxy_http_connections_stat);
00152 Debug("SocksProxy", "Handing over the HTTP request\n");
00153
00154 ha_opt.transport_type = clientVC->attributes;
00155 HttpSessionAccept http_accept(ha_opt);
00156 http_accept.mainEvent(NET_EVENT_ACCEPT, clientVC);
00157 state = ALL_DONE;
00158 break;
00159 }
00160
00161 case RESP_TO_CLIENT:
00162 state = SOCKS_ERROR;
00163 break;
00164
00165 default:
00166 buf->reset();
00167 timeout = this_ethread()
00168 ->schedule_in(this, HRTIME_SECONDS(netProcessor.socks_conf_stuff->socks_timeout));
00169 clientVC->do_io_read(this, INT64_MAX, buf);
00170 }
00171
00172 break;
00173
00174 case VC_EVENT_WRITE_READY:
00175 Debug("SocksProxy", "Received unexpected write_ready\n");
00176 break;
00177
00178 case VC_EVENT_READ_COMPLETE:
00179 Debug("SocksProxy", "Oops! We should never get Read_Complete.\n");
00180
00181 case VC_EVENT_READ_READY:{
00182 unsigned char *port_ptr = 0;
00183
00184 ret = EVENT_CONT;
00185 vio = (VIO *) data;
00186
00187 n_read_avail = reader->block_read_avail();
00188 ink_assert(n_read_avail == reader->read_avail());
00189 p = (unsigned char *) reader->start();
00190
00191 if (n_read_avail >= 2) {
00192
00193 Debug(state == SOCKS_ACCEPT ? "SocksProxy" : "", "Accepted connection from a version %d client\n", (int) p[0]);
00194
00195
00196 switch (p[0]) {
00197
00198 case SOCKS4_VERSION:
00199 ink_assert(state == SOCKS_ACCEPT);
00200
00201 if (n_read_avail > 8) {
00202
00203 int i = 8;
00204 while (p[i] != 0 && n_read_avail > i)
00205 i++;
00206
00207 if (p[i] == 0) {
00208 port_ptr = &p[2];
00209 clientVC->socks_addr.type = SOCKS_ATYPE_IPV4;
00210 reader->consume(i + 1);
00211
00212 ret = EVENT_DONE;
00213 }
00214 }
00215 break;
00216
00217 case SOCKS5_VERSION:
00218
00219 if (state == SOCKS_ACCEPT) {
00220 if (n_read_avail >= 2 + p[1]) {
00221 auth_handler = &socks5ServerAuthHandler;
00222 ret = EVENT_DONE;
00223 }
00224 } else {
00225 ink_assert(state == AUTH_DONE);
00226
00227 if (n_read_avail >= 5) {
00228 int req_len;
00229
00230 switch (p[3]) {
00231 case SOCKS_ATYPE_IPV4:
00232 req_len = 10;
00233 break;
00234 case SOCKS_ATYPE_FQHN:
00235 req_len = 7 + p[4];
00236 break;
00237 case SOCKS_ATYPE_IPV6:
00238 req_len = 22;
00239 break;
00240 default:
00241 req_len = INT_MAX;
00242 Debug("SocksProxy", "Illegal address type(%d)\n", (int) p[3]);
00243 }
00244
00245 if (n_read_avail >= req_len) {
00246 port_ptr = &p[req_len - 2];
00247 clientVC->socks_addr.type = p[3];
00248 auth_handler = NULL;
00249 reader->consume(req_len);
00250 ret = EVENT_DONE;
00251 }
00252 }
00253 }
00254 break;
00255
00256 default:
00257 Warning("Wrong version for Socks: %d\n", p[0]);
00258 state = SOCKS_ERROR;
00259 }
00260 }
00261
00262 if (ret == EVENT_DONE) {
00263 timeout->cancel(this);
00264 timeout = 0;
00265
00266 if (auth_handler) {
00267
00268
00269 vio->nbytes = vio->ndone;
00270
00271
00272 if (invokeSocksAuthHandler(auth_handler, SOCKS_AUTH_READ_COMPLETE, p) >= 0) {
00273 buf->reset();
00274 p = (unsigned char *) buf->start();
00275
00276 int n_bytes = invokeSocksAuthHandler(auth_handler,
00277 SOCKS_AUTH_FILL_WRITE_BUF, p);
00278 ink_assert(n_bytes > 0);
00279
00280 buf->fill(n_bytes);
00281
00282 clientVC->do_io_write(this, n_bytes, reader, 0);
00283
00284 state = AUTH_DONE;
00285 } else {
00286 Debug("SocksProxy", "Auth_handler returned error\n");
00287 state = SOCKS_ERROR;
00288 }
00289
00290 } else {
00291 int port = port_ptr[0] * 256 + port_ptr[1];
00292 version = p[0];
00293
00294 if (port == netProcessor.socks_conf_stuff->http_port && p[1] == SOCKS_CONNECT) {
00295
00296
00297 vio->nbytes = vio->ndone;
00298
00299 ret = setupHttpRequest(p);
00300 sendResp(true);
00301 state = HTTP_REQ;
00302
00303 } else {
00304 SOCKSPROXY_INC_STAT(socksproxy_tunneled_connections_stat);
00305 Debug("SocksProxy", "Tunnelling the connection for port %d", port);
00306
00307 if (clientVC->socks_addr.type != SOCKS_ATYPE_IPV4) {
00308
00309
00310 mainEvent(NET_EVENT_OPEN_FAILED, NULL);
00311 break;
00312 }
00313
00314 uint32_t ip;
00315 struct sockaddr_in addr;
00316
00317 memcpy(&ip, &p[4], 4);
00318 ats_ip4_set(&addr, ip, htons(port));
00319
00320 state = SERVER_TUNNEL;
00321 clientVIO = vio;
00322
00323
00324
00325 NetVCOptions vc_options;
00326 vc_options.socks_support = p[1];
00327 vc_options.socks_version = version;
00328
00329 Action *action = netProcessor.connect_re(this, ats_ip_sa_cast(&addr), &vc_options);
00330 if (action != ACTION_RESULT_DONE) {
00331 ink_assert(pending_action == NULL);
00332 pending_action = action;
00333 }
00334 }
00335 }
00336 }
00337
00338 break;
00339 }
00340
00341 case NET_EVENT_OPEN:{
00342 pending_action = NULL;
00343 ink_assert(state == SERVER_TUNNEL);
00344 Debug("SocksProxy", "open to Socks server succeeded\n");
00345
00346 NetVConnection *serverVC;
00347 serverVC = (NetVConnection *) data;
00348
00349 OneWayTunnel *c_to_s = OneWayTunnel::OneWayTunnel_alloc();
00350 OneWayTunnel *s_to_c = OneWayTunnel::OneWayTunnel_alloc();
00351
00352 c_to_s->init(clientVC, serverVC, NULL, clientVIO, reader);
00353 s_to_c->init(serverVC, clientVC, NULL, 0 ,
00354 c_to_s->mutex);
00355
00356 OneWayTunnel::SetupTwoWayTunnel(c_to_s, s_to_c);
00357
00358 buf = 0;
00359 state = ALL_DONE;
00360 break;
00361 }
00362
00363 case NET_EVENT_OPEN_FAILED:
00364 pending_action = NULL;
00365 sendResp(false);
00366 state = RESP_TO_CLIENT;
00367 Debug("SocksProxy", "open to Socks server failed\n");
00368 break;
00369
00370 case EVENT_INTERVAL:
00371 timeout = 0;
00372 Debug("SocksProxy", "SocksProxy timeout, state = %d\n", state);
00373 state = SOCKS_ERROR;
00374 break;
00375
00376 case VC_EVENT_ERROR:
00377 case VC_EVENT_INACTIVITY_TIMEOUT:
00378 case VC_EVENT_ACTIVE_TIMEOUT:
00379 case VC_EVENT_EOS:
00380 Debug("SocksProxy", "VC_EVENT (state: %d error: %s)\n", state, get_vc_event_name(event));
00381 state = SOCKS_ERROR;
00382 break;
00383
00384 default:
00385 ink_assert(!"bad case value\n");
00386 state = SOCKS_ERROR;
00387 }
00388
00389 if (state == SOCKS_ERROR) {
00390 if (pending_action)
00391 pending_action->cancel();
00392
00393 if (timeout)
00394 timeout->cancel(this);
00395
00396 if (clientVC) {
00397 Debug("SocksProxy", "Closing clientVC on error\n");
00398 clientVC->do_io_close();
00399 clientVC = NULL;
00400 }
00401
00402 state = ALL_DONE;
00403 }
00404
00405 recursion--;
00406
00407 if (state == ALL_DONE && recursion == 0) {
00408 free();
00409 }
00410
00411 return ret;
00412 }
00413
00414 int
00415 SocksProxy::sendResp(bool granted)
00416 {
00417 int n_bytes;
00418
00419
00420
00421
00422
00423
00424
00425
00426 buf->reset();
00427 unsigned char *p = (unsigned char *) buf->start();
00428
00429 if (version == SOCKS4_VERSION) {
00430 p[0] = 0;
00431 p[1] = (granted) ? SOCKS4_REQ_GRANTED : SOCKS4_CONN_FAILED;
00432 n_bytes = 8;
00433 } else {
00434 p[0] = SOCKS5_VERSION;
00435 p[1] = (granted) ? SOCKS5_REQ_GRANTED : SOCKS5_CONN_FAILED;
00436 p[2] = 0;
00437 p[3] = SOCKS_ATYPE_IPV4;
00438 p[4] = p[5] = p[6] = p[7] = p[8] = p[9] = 0;
00439 n_bytes = 10;
00440 }
00441
00442 buf->fill(n_bytes);
00443 clientVC->do_io_write(this, n_bytes, reader, 0);
00444
00445 return n_bytes;
00446 }
00447
00448
00449 int
00450 SocksProxy::setupHttpRequest(unsigned char *p)
00451 {
00452 int ret = EVENT_DONE;
00453
00454 SocksAddrType *a = &clientVC->socks_addr;
00455
00456
00457
00458 switch (a->type) {
00459
00460 case SOCKS_ATYPE_IPV4:
00461 a->addr.ipv4[0] = p[4];
00462 a->addr.ipv4[1] = p[5];
00463 a->addr.ipv4[2] = p[6];
00464 a->addr.ipv4[3] = p[7];
00465 break;
00466
00467 case SOCKS_ATYPE_FQHN:
00468
00469 a->addr.buf = (unsigned char *)ats_malloc(p[4] + 1);
00470 memcpy(a->addr.buf, &p[5], p[4]);
00471 a->addr.buf[p[4]] = 0;
00472 break;
00473 case SOCKS_ATYPE_IPV6:
00474
00475
00476
00477
00478 a->type = SOCKS_ATYPE_IPV4;
00479 a->addr.ipv4[0] = p[16];
00480 a->addr.ipv4[0] = p[17];
00481 a->addr.ipv4[0] = p[18];
00482 a->addr.ipv4[0] = p[19];
00483
00484 break;
00485 default:
00486 ink_assert(!"bad case value");
00487 }
00488
00489 return ret;
00490 }
00491
00492
00493
00494
00495 static void
00496 new_SocksProxy(NetVConnection * netVC)
00497 {
00498 SocksProxy *proxy = socksProxyAllocator.alloc();
00499 proxy->init(netVC);
00500 }
00501
00502 struct SocksAccepter: public Continuation
00503 {
00504
00505 typedef int (SocksAccepter::*SocksAccepterHandler) (int, void *);
00506
00507 int mainEvent(int event, NetVConnection * netVC)
00508 {
00509
00510 ink_assert(event == NET_EVENT_ACCEPT);
00511
00512
00513 new_SocksProxy(netVC);
00514
00515 return EVENT_CONT;
00516 }
00517
00518
00519 SocksAccepter():Continuation(NULL)
00520 {
00521 SET_HANDLER((SocksAccepterHandler) & SocksAccepter::mainEvent);
00522 }
00523 };
00524
00525 void
00526 start_SocksProxy(int port)
00527 {
00528 Debug("SocksProxy", "Accepting SocksProxy connections on port %d\n", port);
00529 NetProcessor::AcceptOptions opt;
00530 opt.local_port = port;
00531 netProcessor.main_accept(new SocksAccepter(), NO_FD, opt);
00532
00533 socksproxy_stat_block = RecAllocateRawStatBlock(socksproxy_stat_count);
00534
00535 if (socksproxy_stat_block) {
00536 RecRegisterRawStat(socksproxy_stat_block, RECT_PROCESS,
00537 "proxy.process.socks.proxy.http_connections",
00538 RECD_INT, RECP_PERSISTENT, socksproxy_http_connections_stat, RecRawStatSyncCount);
00539
00540 RecRegisterRawStat(socksproxy_stat_block, RECT_PROCESS,
00541 "proxy.process.socks.proxy.tunneled_connections",
00542 RECD_INT, RECP_PERSISTENT, socksproxy_tunneled_connections_stat, RecRawStatSyncCount);
00543 }
00544 }
00545
00546 int
00547 socks5ServerAuthHandler(int event, unsigned char *p, void (**h_ptr) (void))
00548 {
00549
00550 int ret = 0;
00551
00552
00553 switch (event) {
00554
00555 case SOCKS_AUTH_READ_COMPLETE:
00556
00557 ink_assert(p[0] == SOCKS5_VERSION);
00558 Debug("SocksProxy", "Socks read initial auth info\n");
00559
00560 break;
00561
00562 case SOCKS_AUTH_FILL_WRITE_BUF:
00563 Debug("SocksProxy", "No authentication is required\n");
00564 p[0] = SOCKS5_VERSION;
00565 p[1] = 0;
00566 ret = 2;
00567
00568 case SOCKS_AUTH_WRITE_COMPLETE:
00569
00570 *h_ptr = NULL;
00571 break;
00572
00573 default:
00574 ink_assert(!"bad case value");
00575 ret = -1;
00576 }
00577
00578 return ret;
00579 }