BSocksClient.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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 <base/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. static void report_error (BSocksClient *o, int error);
  34. static void init_control_io (BSocksClient *o);
  35. static void free_control_io (BSocksClient *o);
  36. static void init_up_io (BSocksClient *o);
  37. static void free_up_io (BSocksClient *o);
  38. static void start_receive (BSocksClient *o, uint8_t *dest, int total);
  39. static void do_receive (BSocksClient *o);
  40. static void connector_handler (BSocksClient* o, int is_error);
  41. static void connection_handler (BSocksClient* o, int event);
  42. static void recv_handler_done (BSocksClient *o, int data_len);
  43. static void send_handler_done (BSocksClient *o);
  44. void report_error (BSocksClient *o, int error)
  45. {
  46. DEBUGERROR(&o->d_err, o->handler(o->user, error))
  47. }
  48. void init_control_io (BSocksClient *o)
  49. {
  50. // init receiving
  51. BConnection_RecvAsync_Init(&o->con);
  52. o->control.recv_if = BConnection_RecvAsync_GetIf(&o->con);
  53. StreamRecvInterface_Receiver_Init(o->control.recv_if, (StreamRecvInterface_handler_done)recv_handler_done, o);
  54. // init sending
  55. BConnection_SendAsync_Init(&o->con);
  56. PacketStreamSender_Init(&o->control.send_sender, BConnection_SendAsync_GetIf(&o->con), sizeof(o->control.msg), BReactor_PendingGroup(o->reactor));
  57. o->control.send_if = PacketStreamSender_GetInput(&o->control.send_sender);
  58. PacketPassInterface_Sender_Init(o->control.send_if, (PacketPassInterface_handler_done)send_handler_done, o);
  59. }
  60. void free_control_io (BSocksClient *o)
  61. {
  62. // free sending
  63. PacketStreamSender_Free(&o->control.send_sender);
  64. BConnection_SendAsync_Free(&o->con);
  65. // free receiving
  66. BConnection_RecvAsync_Free(&o->con);
  67. }
  68. void init_up_io (BSocksClient *o)
  69. {
  70. // init receiving
  71. BConnection_RecvAsync_Init(&o->con);
  72. // init sending
  73. BConnection_SendAsync_Init(&o->con);
  74. }
  75. void free_up_io (BSocksClient *o)
  76. {
  77. // free sending
  78. BConnection_SendAsync_Free(&o->con);
  79. // free receiving
  80. BConnection_RecvAsync_Free(&o->con);
  81. }
  82. void start_receive (BSocksClient *o, uint8_t *dest, int total)
  83. {
  84. ASSERT(total > 0)
  85. o->control.recv_dest = dest;
  86. o->control.recv_len = 0;
  87. o->control.recv_total = total;
  88. do_receive(o);
  89. }
  90. void do_receive (BSocksClient *o)
  91. {
  92. ASSERT(o->control.recv_len < o->control.recv_total)
  93. StreamRecvInterface_Receiver_Recv(o->control.recv_if, o->control.recv_dest + o->control.recv_len, o->control.recv_total - o->control.recv_len);
  94. }
  95. void connector_handler (BSocksClient* o, int is_error)
  96. {
  97. DebugObject_Access(&o->d_obj);
  98. ASSERT(o->state == STATE_CONNECTING)
  99. // check connection result
  100. if (is_error) {
  101. BLog(BLOG_ERROR, "connection failed");
  102. goto fail0;
  103. }
  104. // init connection
  105. if (!BConnection_Init(&o->con, BCONNECTION_SOURCE_CONNECTOR(&o->connector), o->reactor, o, (BConnection_handler)connection_handler)) {
  106. BLog(BLOG_ERROR, "BConnection_Init failed");
  107. goto fail0;
  108. }
  109. BLog(BLOG_DEBUG, "connected");
  110. // init control I/O
  111. init_control_io(o);
  112. // send hello
  113. o->control.msg.client_hello.header.ver = hton8(SOCKS_VERSION);
  114. o->control.msg.client_hello.header.nmethods = hton8(1);
  115. o->control.msg.client_hello.method.method = hton8(SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED);
  116. PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)&o->control.msg.client_hello, sizeof(o->control.msg.client_hello));
  117. // set state
  118. o->state = STATE_SENDING_HELLO;
  119. return;
  120. fail0:
  121. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  122. return;
  123. }
  124. void connection_handler (BSocksClient* o, int event)
  125. {
  126. DebugObject_Access(&o->d_obj);
  127. ASSERT(o->state != STATE_CONNECTING)
  128. if (o->state == STATE_UP && event == BCONNECTION_EVENT_RECVCLOSED) {
  129. report_error(o, BSOCKSCLIENT_EVENT_ERROR_CLOSED);
  130. return;
  131. }
  132. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  133. return;
  134. }
  135. void recv_handler_done (BSocksClient *o, int data_len)
  136. {
  137. ASSERT(data_len >= 0)
  138. ASSERT(data_len <= o->control.recv_total - o->control.recv_len)
  139. DebugObject_Access(&o->d_obj);
  140. o->control.recv_len += data_len;
  141. if (o->control.recv_len < o->control.recv_total) {
  142. do_receive(o);
  143. return;
  144. }
  145. switch (o->state) {
  146. case STATE_SENT_HELLO: {
  147. BLog(BLOG_DEBUG, "received hello");
  148. if (ntoh8(o->control.msg.server_hello.ver != SOCKS_VERSION)) {
  149. BLog(BLOG_NOTICE, "wrong version");
  150. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  151. return;
  152. }
  153. if (ntoh8(o->control.msg.server_hello.method != SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED)) {
  154. BLog(BLOG_NOTICE, "wrong method");
  155. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  156. return;
  157. }
  158. // send request
  159. o->control.msg.request.header.ver = hton8(SOCKS_VERSION);
  160. o->control.msg.request.header.cmd = hton8(SOCKS_CMD_CONNECT);
  161. o->control.msg.request.header.rsv = hton8(0);
  162. int len = sizeof(o->control.msg.request.header);
  163. switch (o->dest_addr.type) {
  164. case BADDR_TYPE_IPV4:
  165. o->control.msg.request.header.atyp = hton8(SOCKS_ATYP_IPV4);
  166. o->control.msg.request.addr.ipv4.addr = o->dest_addr.ipv4.ip;
  167. o->control.msg.request.addr.ipv4.port = o->dest_addr.ipv4.port;
  168. len += sizeof(o->control.msg.request.addr.ipv4);
  169. break;
  170. case BADDR_TYPE_IPV6:
  171. o->control.msg.request.header.atyp = hton8(SOCKS_ATYP_IPV6);
  172. memcpy(o->control.msg.request.addr.ipv6.addr, o->dest_addr.ipv6.ip, sizeof(o->dest_addr.ipv6.ip));
  173. o->control.msg.request.addr.ipv6.port = o->dest_addr.ipv6.port;
  174. len += sizeof(o->control.msg.request.addr.ipv6);
  175. break;
  176. default:
  177. ASSERT(0);
  178. }
  179. PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)&o->control.msg.request, len);
  180. // set state
  181. o->state = STATE_SENDING_REQUEST;
  182. } break;
  183. case STATE_SENT_REQUEST: {
  184. BLog(BLOG_DEBUG, "received reply header");
  185. if (ntoh8(o->control.msg.reply.header.ver) != SOCKS_VERSION) {
  186. BLog(BLOG_NOTICE, "wrong version");
  187. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  188. return;
  189. }
  190. if (ntoh8(o->control.msg.reply.header.rep) != SOCKS_REP_SUCCEEDED) {
  191. BLog(BLOG_NOTICE, "reply not successful");
  192. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  193. return;
  194. }
  195. int addr_len;
  196. switch (ntoh8(o->control.msg.reply.header.atyp)) {
  197. case SOCKS_ATYP_IPV4:
  198. addr_len = sizeof(o->control.msg.reply.addr.ipv4);
  199. break;
  200. case SOCKS_ATYP_IPV6:
  201. addr_len = sizeof(o->control.msg.reply.addr.ipv6);
  202. break;
  203. default:
  204. BLog(BLOG_NOTICE, "reply has unknown address type");
  205. report_error(o, BSOCKSCLIENT_EVENT_ERROR);
  206. return;
  207. }
  208. // receive the rest of the reply
  209. start_receive(o, (uint8_t *)&o->control.msg.reply.addr, addr_len);
  210. // set state
  211. o->state = STATE_RECEIVED_REPLY_HEADER;
  212. } break;
  213. case STATE_RECEIVED_REPLY_HEADER: {
  214. BLog(BLOG_DEBUG, "received reply rest");
  215. // free control I/O
  216. free_control_io(o);
  217. // init up I/O
  218. init_up_io(o);
  219. // set state
  220. o->state = STATE_UP;
  221. // call handler
  222. o->handler(o->user, BSOCKSCLIENT_EVENT_UP);
  223. return;
  224. } break;
  225. default:
  226. ASSERT(0);
  227. }
  228. }
  229. void send_handler_done (BSocksClient *o)
  230. {
  231. DebugObject_Access(&o->d_obj);
  232. switch (o->state) {
  233. case STATE_SENDING_HELLO: {
  234. BLog(BLOG_DEBUG, "sent hello");
  235. // receive hello
  236. start_receive(o, (uint8_t *)&o->control.msg.server_hello, sizeof(o->control.msg.server_hello));
  237. // set state
  238. o->state = STATE_SENT_HELLO;
  239. } break;
  240. case STATE_SENDING_REQUEST: {
  241. BLog(BLOG_DEBUG, "sent request");
  242. // receive reply header
  243. start_receive(o, (uint8_t *)&o->control.msg.reply.header, sizeof(o->control.msg.reply.header));
  244. // set state
  245. o->state = STATE_SENT_REQUEST;
  246. } break;
  247. default:
  248. ASSERT(0);
  249. }
  250. }
  251. int BSocksClient_Init (BSocksClient *o, BAddr server_addr, BAddr dest_addr, BSocksClient_handler handler, void *user, BReactor *reactor)
  252. {
  253. ASSERT(!BAddr_IsInvalid(&server_addr))
  254. ASSERT(dest_addr.type == BADDR_TYPE_IPV4 || dest_addr.type == BADDR_TYPE_IPV6)
  255. // init arguments
  256. o->dest_addr = dest_addr;
  257. o->handler = handler;
  258. o->user = user;
  259. o->reactor = reactor;
  260. // init connector
  261. if (!BConnector_Init(&o->connector, server_addr, o->reactor, o, (BConnector_handler)connector_handler)) {
  262. BLog(BLOG_ERROR, "BConnector_Init failed");
  263. goto fail0;
  264. }
  265. // set state
  266. o->state = STATE_CONNECTING;
  267. DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor));
  268. DebugObject_Init(&o->d_obj);
  269. return 1;
  270. fail0:
  271. return 0;
  272. }
  273. void BSocksClient_Free (BSocksClient *o)
  274. {
  275. DebugObject_Free(&o->d_obj);
  276. DebugError_Free(&o->d_err);
  277. if (o->state != STATE_CONNECTING) {
  278. if (o->state == STATE_UP) {
  279. // free up I/O
  280. free_up_io(o);
  281. } else {
  282. ASSERT(o->state == STATE_SENDING_HELLO || o->state == STATE_SENT_HELLO ||
  283. o->state == STATE_SENDING_REQUEST || o->state == STATE_SENT_REQUEST ||
  284. o->state == STATE_RECEIVED_REPLY_HEADER
  285. )
  286. // free control I/O
  287. free_control_io(o);
  288. }
  289. // free connection
  290. BConnection_Free(&o->con);
  291. }
  292. // free connector
  293. BConnector_Free(&o->connector);
  294. }
  295. StreamPassInterface * BSocksClient_GetSendInterface (BSocksClient *o)
  296. {
  297. ASSERT(o->state == STATE_UP)
  298. DebugObject_Access(&o->d_obj);
  299. return BConnection_SendAsync_GetIf(&o->con);
  300. }
  301. StreamRecvInterface * BSocksClient_GetRecvInterface (BSocksClient *o)
  302. {
  303. ASSERT(o->state == STATE_UP)
  304. DebugObject_Access(&o->d_obj);
  305. return BConnection_RecvAsync_GetIf(&o->con);
  306. }