BSocksClient.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /**
  2. * @file BSocksClient.c
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * This file is part of BadVPN.
  8. *
  9. * BadVPN is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * BadVPN is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. */
  22. #include <misc/byteorder.h>
  23. #include <system/BLog.h>
  24. #include <socksclient/BSocksClient.h>
  25. #include <generated/blog_channel_BSocksClient.h>
  26. #define STATE_CONNECTING 1
  27. #define STATE_SENDING_HELLO 2
  28. #define STATE_SENT_HELLO 3
  29. #define STATE_SENDING_REQUEST 4
  30. #define STATE_SENT_REQUEST 5
  31. #define STATE_RECEIVED_REPLY_HEADER 6
  32. #define STATE_UP 7
  33. #define COMPONENT_SOURCE 1
  34. #define COMPONENT_SINK 2
  35. static void report_error (BSocksClient *o, int error);
  36. static void init_control_io (BSocksClient *o);
  37. static void free_control_io (BSocksClient *o);
  38. static void init_up_io (BSocksClient *o);
  39. static void free_up_io (BSocksClient *o);
  40. static void start_receive (BSocksClient *o, uint8_t *dest, int total);
  41. static void do_receive (BSocksClient *o);
  42. static void error_handler (BSocksClient *o, int component, const void *data);
  43. static void socket_error_handler (BSocksClient *o, int event);
  44. static void connect_handler (BSocksClient *o, int event);
  45. static void recv_handler_done (BSocksClient *o, int data_len);
  46. static void send_handler_done (BSocksClient *o);
  47. void report_error (BSocksClient *o, int error)
  48. {
  49. #ifndef NDEBUG
  50. DEAD_ENTER(o->d_dead)
  51. #endif
  52. o->handler(o->user, error);
  53. #ifndef NDEBUG
  54. ASSERT(DEAD_KILLED)
  55. DEAD_LEAVE(o->d_dead);
  56. #endif
  57. }
  58. void init_control_io (BSocksClient *o)
  59. {
  60. // init receiving
  61. StreamSocketSource_Init(&o->control.recv_source, FlowErrorReporter_Create(&o->domain, COMPONENT_SOURCE), &o->sock, BReactor_PendingGroup(o->reactor));
  62. o->control.recv_if = StreamSocketSource_GetOutput(&o->control.recv_source);
  63. StreamRecvInterface_Receiver_Init(o->control.recv_if, (StreamRecvInterface_handler_done)recv_handler_done, o);
  64. // init sending
  65. StreamSocketSink_Init(&o->control.send_sink, FlowErrorReporter_Create(&o->domain, COMPONENT_SINK), &o->sock, BReactor_PendingGroup(o->reactor));
  66. PacketStreamSender_Init(&o->control.send_sender, StreamSocketSink_GetInput(&o->control.send_sink), sizeof(o->control.msg), BReactor_PendingGroup(o->reactor));
  67. o->control.send_if = PacketStreamSender_GetInput(&o->control.send_sender);
  68. PacketPassInterface_Sender_Init(o->control.send_if, (PacketPassInterface_handler_done)send_handler_done, o);
  69. }
  70. void free_control_io (BSocksClient *o)
  71. {
  72. // free sending
  73. PacketStreamSender_Free(&o->control.send_sender);
  74. StreamSocketSink_Free(&o->control.send_sink);
  75. // free receiving
  76. StreamSocketSource_Free(&o->control.recv_source);
  77. }
  78. void init_up_io (BSocksClient *o)
  79. {
  80. // init receiving
  81. StreamSocketSource_Init(&o->up.recv_source, FlowErrorReporter_Create(&o->domain, COMPONENT_SOURCE), &o->sock, BReactor_PendingGroup(o->reactor));
  82. // init sending
  83. StreamSocketSink_Init(&o->up.send_sink, FlowErrorReporter_Create(&o->domain, COMPONENT_SINK), &o->sock, BReactor_PendingGroup(o->reactor));
  84. }
  85. void free_up_io (BSocksClient *o)
  86. {
  87. // free sending
  88. StreamSocketSink_Free(&o->up.send_sink);
  89. // free receiving
  90. StreamSocketSource_Free(&o->up.recv_source);
  91. }
  92. void start_receive (BSocksClient *o, uint8_t *dest, int total)
  93. {
  94. ASSERT(total > 0)
  95. o->control.recv_dest = dest;
  96. o->control.recv_len = 0;
  97. o->control.recv_total = total;
  98. do_receive(o);
  99. }
  100. void do_receive (BSocksClient *o)
  101. {
  102. ASSERT(o->control.recv_len < o->control.recv_total)
  103. StreamRecvInterface_Receiver_Recv(o->control.recv_if, o->control.recv_dest + o->control.recv_len, o->control.recv_total - o->control.recv_len);
  104. }
  105. void error_handler (BSocksClient *o, int component, const void *data)
  106. {
  107. ASSERT(component == COMPONENT_SOURCE || component == COMPONENT_SINK)
  108. DebugObject_Access(&o->d_obj);
  109. if (o->state == STATE_UP && component == COMPONENT_SOURCE && *((int *)data) == STREAMSOCKETSOURCE_ERROR_CLOSED) {
  110. BLog(BLOG_DEBUG, "connection closed");
  111. report_error(o, BSOCKSCLIENT_EVENT_ERROR_CLOSED);
  112. return;
  113. }
  114. BLog(BLOG_NOTICE, "socket error (%d)", BSocket_GetError(&o->sock));
  115. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  116. return;
  117. }
  118. void socket_error_handler (BSocksClient *o, int event)
  119. {
  120. ASSERT(event == BSOCKET_ERROR)
  121. DebugObject_Access(&o->d_obj);
  122. BLog(BLOG_NOTICE, "socket error event");
  123. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  124. return;
  125. }
  126. void connect_handler (BSocksClient *o, int event)
  127. {
  128. ASSERT(event == BSOCKET_CONNECT)
  129. ASSERT(o->state == STATE_CONNECTING)
  130. DebugObject_Access(&o->d_obj);
  131. // remove event handler
  132. BSocket_RemoveEventHandler(&o->sock, BSOCKET_CONNECT);
  133. // check connect result
  134. int res = BSocket_GetConnectResult(&o->sock);
  135. if (res != 0) {
  136. BLog(BLOG_NOTICE, "connection failed (%d)", res);
  137. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  138. return;
  139. }
  140. BLog(BLOG_DEBUG, "connected");
  141. // init control I/O
  142. init_control_io(o);
  143. // send hello
  144. o->control.msg.client_hello.header.ver = hton8(SOCKS_VERSION);
  145. o->control.msg.client_hello.header.nmethods = hton8(1);
  146. o->control.msg.client_hello.method.method = hton8(SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED);
  147. PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)&o->control.msg.client_hello, sizeof(o->control.msg.client_hello));
  148. // set state
  149. o->state = STATE_SENDING_HELLO;
  150. }
  151. void recv_handler_done (BSocksClient *o, int data_len)
  152. {
  153. ASSERT(data_len >= 0)
  154. ASSERT(data_len <= o->control.recv_total - o->control.recv_len)
  155. DebugObject_Access(&o->d_obj);
  156. o->control.recv_len += data_len;
  157. if (o->control.recv_len < o->control.recv_total) {
  158. do_receive(o);
  159. return;
  160. }
  161. switch (o->state) {
  162. case STATE_SENT_HELLO: {
  163. BLog(BLOG_DEBUG, "received hello");
  164. if (ntoh8(o->control.msg.server_hello.ver != SOCKS_VERSION)) {
  165. BLog(BLOG_NOTICE, "wrong version");
  166. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  167. return;
  168. }
  169. if (ntoh8(o->control.msg.server_hello.method != SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED)) {
  170. BLog(BLOG_NOTICE, "wrong method");
  171. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  172. return;
  173. }
  174. // send request
  175. o->control.msg.request.header.ver = hton8(SOCKS_VERSION);
  176. o->control.msg.request.header.cmd = hton8(SOCKS_CMD_CONNECT);
  177. o->control.msg.request.header.rsv = hton8(0);
  178. int len = sizeof(o->control.msg.request.header);
  179. switch (o->dest_addr.type) {
  180. case BADDR_TYPE_IPV4:
  181. o->control.msg.request.header.atyp = hton8(SOCKS_ATYP_IPV4);
  182. o->control.msg.request.addr.ipv4.addr = o->dest_addr.ipv4.ip;
  183. o->control.msg.request.addr.ipv4.port = o->dest_addr.ipv4.port;
  184. len += sizeof(o->control.msg.request.addr.ipv4);
  185. break;
  186. case BADDR_TYPE_IPV6:
  187. o->control.msg.request.header.atyp = hton8(SOCKS_ATYP_IPV6);
  188. memcpy(o->control.msg.request.addr.ipv6.addr, o->dest_addr.ipv6.ip, sizeof(o->dest_addr.ipv6.ip));
  189. o->control.msg.request.addr.ipv6.port = o->dest_addr.ipv6.port;
  190. len += sizeof(o->control.msg.request.addr.ipv6);
  191. break;
  192. default:
  193. ASSERT(0);
  194. }
  195. PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)&o->control.msg.request, len);
  196. // set state
  197. o->state = STATE_SENDING_REQUEST;
  198. } break;
  199. case STATE_SENT_REQUEST: {
  200. BLog(BLOG_DEBUG, "received reply header");
  201. if (ntoh8(o->control.msg.reply.header.ver) != SOCKS_VERSION) {
  202. BLog(BLOG_NOTICE, "wrong version");
  203. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  204. return;
  205. }
  206. if (ntoh8(o->control.msg.reply.header.rep) != SOCKS_REP_SUCCEEDED) {
  207. BLog(BLOG_NOTICE, "reply not successful");
  208. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  209. return;
  210. }
  211. int addr_len;
  212. switch (ntoh8(o->control.msg.reply.header.atyp)) {
  213. case SOCKS_ATYP_IPV4:
  214. addr_len = sizeof(o->control.msg.reply.addr.ipv4);
  215. break;
  216. case SOCKS_ATYP_IPV6:
  217. addr_len = sizeof(o->control.msg.reply.addr.ipv6);
  218. break;
  219. default:
  220. BLog(BLOG_NOTICE, "reply has unknown address type");
  221. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  222. return;
  223. }
  224. // receive the rest of the reply
  225. start_receive(o, (uint8_t *)&o->control.msg.reply.addr, addr_len);
  226. // set state
  227. o->state = STATE_RECEIVED_REPLY_HEADER;
  228. } break;
  229. case STATE_RECEIVED_REPLY_HEADER: {
  230. BLog(BLOG_DEBUG, "received reply rest");
  231. // free control I/O
  232. free_control_io(o);
  233. // init up I/O
  234. init_up_io(o);
  235. // set state
  236. o->state = STATE_UP;
  237. // call handler
  238. o->handler(o->user, BSOCKSCLIENT_EVENT_UP);
  239. return;
  240. } break;
  241. default:
  242. ASSERT(0);
  243. }
  244. }
  245. void send_handler_done (BSocksClient *o)
  246. {
  247. DebugObject_Access(&o->d_obj);
  248. switch (o->state) {
  249. case STATE_SENDING_HELLO: {
  250. BLog(BLOG_DEBUG, "sent hello");
  251. // receive hello
  252. start_receive(o, (uint8_t *)&o->control.msg.server_hello, sizeof(o->control.msg.server_hello));
  253. // set state
  254. o->state = STATE_SENT_HELLO;
  255. } break;
  256. case STATE_SENDING_REQUEST: {
  257. BLog(BLOG_DEBUG, "sent request");
  258. // receive reply header
  259. start_receive(o, (uint8_t *)&o->control.msg.reply.header, sizeof(o->control.msg.reply.header));
  260. // set state
  261. o->state = STATE_SENT_REQUEST;
  262. } break;
  263. default:
  264. ASSERT(0);
  265. }
  266. }
  267. int BSocksClient_Init (BSocksClient *o, BAddr server_addr, BAddr dest_addr, BSocksClient_handler handler, void *user, BReactor *reactor)
  268. {
  269. ASSERT(dest_addr.type == BADDR_TYPE_IPV4 || dest_addr.type == BADDR_TYPE_IPV6)
  270. // init arguments
  271. o->dest_addr = dest_addr;
  272. o->handler = handler;
  273. o->user = user;
  274. o->reactor = reactor;
  275. // init error domain
  276. FlowErrorDomain_Init(&o->domain, (FlowErrorDomain_handler)error_handler, o);
  277. // init socket
  278. if (BSocket_Init(&o->sock, o->reactor, server_addr.type, BSOCKET_TYPE_STREAM) < 0) {
  279. BLog(BLOG_NOTICE, "BSocket_Init failed");
  280. goto fail0;
  281. }
  282. // connect socket
  283. if (BSocket_Connect(&o->sock, &server_addr) >= 0 || BSocket_GetError(&o->sock) != BSOCKET_ERROR_IN_PROGRESS) {
  284. BLog(BLOG_NOTICE, "BSocket_Connect failed");
  285. goto fail1;
  286. }
  287. // setup error event
  288. BSocket_AddEventHandler(&o->sock, BSOCKET_ERROR, (BSocket_handler)socket_error_handler, o);
  289. BSocket_EnableEvent(&o->sock, BSOCKET_ERROR);
  290. // setup connect event
  291. BSocket_AddEventHandler(&o->sock, BSOCKET_CONNECT, (BSocket_handler)connect_handler, o);
  292. BSocket_EnableEvent(&o->sock, BSOCKET_CONNECT);
  293. // set state
  294. o->state = STATE_CONNECTING;
  295. DebugObject_Init(&o->d_obj);
  296. #ifndef NDEBUG
  297. DEAD_INIT(o->d_dead);
  298. #endif
  299. return 1;
  300. fail1:
  301. BSocket_Free(&o->sock);
  302. fail0:
  303. return 0;
  304. }
  305. void BSocksClient_Free (BSocksClient *o)
  306. {
  307. #ifndef NDEBUG
  308. DEAD_KILL(o->d_dead);
  309. #endif
  310. DebugObject_Free(&o->d_obj);
  311. if (o->state == STATE_UP) {
  312. // free up I/O
  313. free_up_io(o);
  314. }
  315. else if (o->state != STATE_CONNECTING) {
  316. ASSERT(o->state == STATE_SENDING_HELLO || o->state == STATE_SENT_HELLO ||
  317. o->state == STATE_SENDING_REQUEST || o->state == STATE_SENT_REQUEST ||
  318. o->state == STATE_RECEIVED_REPLY_HEADER
  319. )
  320. // free control I/O
  321. free_control_io(o);
  322. }
  323. // free socket
  324. BSocket_Free(&o->sock);
  325. }
  326. StreamPassInterface * BSocksClient_GetSendInterface (BSocksClient *o)
  327. {
  328. ASSERT(o->state == STATE_UP)
  329. DebugObject_Access(&o->d_obj);
  330. return StreamSocketSink_GetInput(&o->up.send_sink);
  331. }
  332. StreamRecvInterface * BSocksClient_GetRecvInterface (BSocksClient *o)
  333. {
  334. ASSERT(o->state == STATE_UP)
  335. DebugObject_Access(&o->d_obj);
  336. return StreamSocketSource_GetOutput(&o->up.recv_source);
  337. }