3838#include <generated/blog_channel_BSocksClient.h>
3939
4040#define STATE_CONNECTING 1
41- #define STATE_SENDING_HELLO 2
42- #define STATE_SENT_HELLO 3
43- #define STATE_SENDING_PASSWORD 10
44- #define STATE_SENT_PASSWORD 11
45- #define STATE_SENDING_REQUEST 4
46- #define STATE_SENT_REQUEST 5
47- #define STATE_RECEIVED_REPLY_HEADER 6
48- #define STATE_UP 7
41+ #define STATE_CONNECTED_HANDLER 2
42+ #define STATE_SENDING_HELLO 3
43+ #define STATE_SENT_HELLO 4
44+ #define STATE_SENDING_PASSWORD 5
45+ #define STATE_SENT_PASSWORD 6
46+ #define STATE_SENDING_REQUEST 7
47+ #define STATE_SENT_REQUEST 8
48+ #define STATE_RECEIVED_REPLY_HEADER 9
49+ #define STATE_UP 10
4950
5051static void report_error (BSocksClient * o , int error );
5152static void init_control_io (BSocksClient * o );
@@ -57,6 +58,7 @@ static void start_receive (BSocksClient *o, uint8_t *dest, int total);
5758static void do_receive (BSocksClient * o );
5859static void connector_handler (BSocksClient * o , int is_error );
5960static void connection_handler (BSocksClient * o , int event );
61+ static void continue_job_handler (BSocksClient * o );
6062static void recv_handler_done (BSocksClient * o , int data_len );
6163static void send_handler_done (BSocksClient * o );
6264static void auth_finished (BSocksClient * p );
@@ -166,12 +168,45 @@ void connector_handler (BSocksClient* o, int is_error)
166168 // init control I/O
167169 init_control_io (o );
168170
171+ // go to STATE_CONNECTED_HANDLER and set the continue job in order to continue
172+ // in continue_job_handler
173+ o -> state = STATE_CONNECTED_HANDLER ;
174+ BPending_Set (& o -> continue_job );
175+
176+ // call the handler with the connected event
177+ o -> handler (o -> user , BSOCKSCLIENT_EVENT_CONNECTED );
178+ return ;
179+
180+ fail0 :
181+ report_error (o , BSOCKSCLIENT_EVENT_ERROR );
182+ return ;
183+ }
184+
185+ void connection_handler (BSocksClient * o , int event )
186+ {
187+ DebugObject_Access (& o -> d_obj );
188+ ASSERT (o -> state != STATE_CONNECTING )
189+
190+ if (o -> state == STATE_UP && event == BCONNECTION_EVENT_RECVCLOSED ) {
191+ report_error (o , BSOCKSCLIENT_EVENT_ERROR_CLOSED );
192+ return ;
193+ }
194+
195+ report_error (o , BSOCKSCLIENT_EVENT_ERROR );
196+ return ;
197+ }
198+
199+ void continue_job_handler (BSocksClient * o )
200+ {
201+ DebugObject_Access (& o -> d_obj );
202+ ASSERT (o -> state == STATE_CONNECTED_HANDLER )
203+
169204 // check number of methods
170205 if (o -> num_auth_info == 0 || o -> num_auth_info > 255 ) {
171206 BLog (BLOG_ERROR , "invalid number of authentication methods" );
172- goto fail1 ;
207+ goto fail0 ;
173208 }
174-
209+
175210 // allocate buffer for sending hello
176211 bsize_t size = bsize_add (
177212 bsize_fromsize (sizeof (struct socks_client_hello_header )),
@@ -181,7 +216,7 @@ void connector_handler (BSocksClient* o, int is_error)
181216 )
182217 );
183218 if (!reserve_buffer (o , size )) {
184- goto fail1 ;
219+ goto fail0 ;
185220 }
186221
187222 // write hello header
@@ -202,27 +237,10 @@ void connector_handler (BSocksClient* o, int is_error)
202237
203238 // set state
204239 o -> state = STATE_SENDING_HELLO ;
205-
206- return ;
207-
208- fail1 :
209- free_control_io (o );
210- BConnection_Free (& o -> con );
211- fail0 :
212- report_error (o , BSOCKSCLIENT_EVENT_ERROR );
240+
213241 return ;
214- }
215242
216- void connection_handler (BSocksClient * o , int event )
217- {
218- DebugObject_Access (& o -> d_obj );
219- ASSERT (o -> state != STATE_CONNECTING )
220-
221- if (o -> state == STATE_UP && event == BCONNECTION_EVENT_RECVCLOSED ) {
222- report_error (o , BSOCKSCLIENT_EVENT_ERROR_CLOSED );
223- return ;
224- }
225-
243+ fail0 :
226244 report_error (o , BSOCKSCLIENT_EVENT_ERROR );
227245 return ;
228246}
@@ -491,8 +509,16 @@ void auth_finished (BSocksClient *o)
491509 // allocate request buffer
492510 bsize_t size = bsize_fromsize (sizeof (struct socks_request_header ));
493511 switch (o -> dest_addr .type ) {
494- case BADDR_TYPE_IPV4 : size = bsize_add (size , bsize_fromsize (sizeof (struct socks_addr_ipv4 ))); break ;
495- case BADDR_TYPE_IPV6 : size = bsize_add (size , bsize_fromsize (sizeof (struct socks_addr_ipv6 ))); break ;
512+ case BADDR_TYPE_IPV4 :
513+ size = bsize_add (size , bsize_fromsize (sizeof (struct socks_addr_ipv4 )));
514+ break ;
515+ case BADDR_TYPE_IPV6 :
516+ size = bsize_add (size , bsize_fromsize (sizeof (struct socks_addr_ipv6 )));
517+ break ;
518+ default :
519+ BLog (BLOG_ERROR , "Invalid dest_addr address type." );
520+ report_error (o , BSOCKSCLIENT_EVENT_ERROR );
521+ return ;
496522 }
497523 if (!reserve_buffer (o , size )) {
498524 report_error (o , BSOCKSCLIENT_EVENT_ERROR );
@@ -549,12 +575,11 @@ struct BSocksClient_auth_info BSocksClient_auth_password (const char *username,
549575 return info ;
550576}
551577
552- int BSocksClient_Init (BSocksClient * o ,
553- BAddr server_addr , const struct BSocksClient_auth_info * auth_info , size_t num_auth_info ,
554- BAddr dest_addr , bool udp , BSocksClient_handler handler , void * user , BReactor * reactor )
578+ int BSocksClient_Init (BSocksClient * o , BAddr server_addr ,
579+ const struct BSocksClient_auth_info * auth_info , size_t num_auth_info , BAddr dest_addr ,
580+ bool udp , BSocksClient_handler handler , void * user , BReactor * reactor )
555581{
556582 ASSERT (!BAddr_IsInvalid (& server_addr ))
557- ASSERT (dest_addr .type == BADDR_TYPE_IPV4 || dest_addr .type == BADDR_TYPE_IPV6 )
558583#ifndef NDEBUG
559584 for (size_t i = 0 ; i < num_auth_info ; i ++ ) {
560585 ASSERT (auth_info [i ].auth_type == SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED ||
@@ -573,6 +598,10 @@ int BSocksClient_Init (BSocksClient *o,
573598
574599 // set no buffer
575600 o -> buffer = NULL ;
601+
602+ // init continue_job
603+ BPending_Init (& o -> continue_job , BReactor_PendingGroup (o -> reactor ),
604+ (BPending_handler )continue_job_handler , o );
576605
577606 // init connector
578607 if (!BConnector_Init (& o -> connector , server_addr , o -> reactor , o , (BConnector_handler )connector_handler )) {
@@ -588,6 +617,7 @@ int BSocksClient_Init (BSocksClient *o,
588617 return 1 ;
589618
590619fail0 :
620+ BPending_Free (& o -> continue_job );
591621 return 0 ;
592622}
593623
@@ -612,12 +642,31 @@ void BSocksClient_Free (BSocksClient *o)
612642 // free connector
613643 BConnector_Free (& o -> connector );
614644
645+ // free continue job
646+ BPending_Free (& o -> continue_job );
647+
615648 // free buffer
616649 if (o -> buffer ) {
617650 BFree (o -> buffer );
618651 }
619652}
620653
654+ int BSocksClient_GetLocalAddr (BSocksClient * o , BAddr * local_addr )
655+ {
656+ ASSERT (o -> state != STATE_CONNECTING )
657+ DebugObject_Access (& o -> d_obj );
658+
659+ return BConnection_GetLocalAddress (& o -> con , local_addr );
660+ }
661+
662+ void BSocksClient_SetDestAddr (BSocksClient * o , BAddr dest_addr )
663+ {
664+ ASSERT (o -> state == STATE_CONNECTING || o -> state == STATE_CONNECTED_HANDLER )
665+ DebugObject_Access (& o -> d_obj );
666+
667+ o -> dest_addr = dest_addr ;
668+ }
669+
621670BAddr BSocksClient_GetBindAddr (BSocksClient * o )
622671{
623672 ASSERT (o -> state == STATE_UP )
0 commit comments