Skip to content

Add connection status feedback for socks proxy connections. #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions broker.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,20 @@ int broker(){
goto RETURN;
}

}else if(message->header_type == DT_CONNECTION_HT_CONNECTED){

if((retval = handle_message_dt_connection_ht_connected()) == -1){
report_error("broker(): handle_message_dt_connection_ht_connected(): %s", strerror(errno));
goto RETURN;
}

}else if(message->header_type == DT_CONNECTION_HT_REFUSED){

if((retval = handle_message_dt_connection_ht_refused()) == -1){
report_error("broker(): handle_message_dt_connection_ht_refused(): %s", strerror(errno));
goto RETURN;
}

}else{
// Unknown connection type. Report but soldier on.
report_error("broker(): Unknown Connection Header Type: %d: Ignoring.", message->header_type);
Expand Down
11 changes: 9 additions & 2 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,13 @@
#define CON_DORMANT 4

/* Apparently reply strings for socks requests are static in the modern era. */
#define SOCKS_V4_REPLY "\x00\x5a\x00\x00\x00\x00\x00\x00"
#define SOCKS_V4_REPLY_OK "\x00\x5a\x00\x00\x00\x00\x00\x00"
#define SOCKS_V4_REPLY_ERR "\x00\x5b\x00\x00\x00\x00\x00\x00"
#define SOCKS_V4_REPLY_LEN 8
#define SOCKS_V5_AUTH_REPLY "\x05\x00"
#define SOCKS_V5_AUTH_REPLY_LEN 2
#define SOCKS_V5_REPLY "\x05\x00\x00\x01\x00\x00\x00\x00\x00\x00"
#define SOCKS_V5_REPLY_OK "\x05\x00\x00\x01\x00\x00\x00\x00\x00\x00"
#define SOCKS_V5_REPLY_ERR "\x05\x01\x00\x01\x00\x00\x00\x00\x00\x00"
#define SOCKS_V5_REPLY_LEN 10

/* Maximum possible size of a socks request. */
Expand Down Expand Up @@ -203,6 +205,8 @@ int handle_message_dt_connection_ht_create_tun_tap();
int handle_message_dt_connection_ht_response();
int handle_connection_activate(struct connection_node *cur_connection_node);
int handle_message_dt_connection_ht_active_dormant();
int handle_message_dt_connection_ht_connected();
int handle_message_dt_connection_ht_refused();
int handle_message_dt_connection_ht_data();
int handle_proxy_read(struct proxy_node *cur_proxy_node);
int handle_connection_write(struct connection_node *cur_connection_node);
Expand All @@ -213,6 +217,8 @@ int handle_send_dt_proxy_ht_create(char *proxy_string, int proxy_type);
int handle_send_dt_proxy_ht_report(struct proxy_node *cur_proxy_node);
int handle_send_dt_connection_ht_destroy(unsigned short origin, unsigned short id, unsigned short header_errno);
int handle_send_dt_connection_ht_create(struct connection_node *cur_connection_node);
int handle_send_dt_connection_ht_connected(unsigned short origin, unsigned short id);
int handle_send_dt_connection_ht_refused(unsigned short origin, unsigned short id);
int handle_send_dt_nop();
struct connection_node *handle_tun_tap_init(int ifr_flag);

Expand Down Expand Up @@ -253,6 +259,7 @@ struct connection_node *connection_node_create();
void connection_node_delete(struct connection_node *);
struct connection_node *connection_node_find(unsigned short origin, unsigned short id);
void connection_node_queue(struct connection_node *cur_connection_node);
void connection_node_socks_reply(struct connection_node *, int ok);
int parse_socks_request(struct connection_node *cur_connection_node);
char *addr_to_string(int atype, char *addr, char *port, int len);

Expand Down
164 changes: 142 additions & 22 deletions handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ int handle_message_dt_connection_ht_create(){
cur_connection_node->origin = message->header_origin;
cur_connection_node->id = message->header_id;
cur_connection_node->proxy_type = message->header_proxy_type;
cur_connection_node->socks_type = message->header_socks_type;

if((cur_connection_node->rhost_rport = (char *) calloc(message->data_len + 1, sizeof(char))) == NULL){
report_error("handle_message_dt_connection_ht_create(): calloc(%d, %d): %s", message->data_len + 1, (int) sizeof(char), strerror(errno));
Expand Down Expand Up @@ -581,6 +582,11 @@ int handle_connection_activate(struct connection_node *cur_connection_node){
fprintf(stderr, "\rConnection failed: %s, %s\n", cur_connection_node->rhost_rport, strerror(optval));
}

if(handle_send_dt_connection_ht_refused(cur_connection_node->origin, cur_connection_node->id) == -1){
report_error("handle_connection_activate(): handle_send_dt_connection_ht_refused(%d, %d, 0): %s", cur_connection_node->origin, cur_connection_node->id, strerror(errno));
return(-1);
}

if(handle_send_dt_connection_ht_destroy(cur_connection_node->origin, cur_connection_node->id, 0) == -1){
report_error("handle_connection_activate(): handle_send_dt_connection_ht_destroy(%d, %d, 0): %s", cur_connection_node->origin, cur_connection_node->id, strerror(errno));
return(-1);
Expand All @@ -592,6 +598,8 @@ int handle_connection_activate(struct connection_node *cur_connection_node){

cur_connection_node->state = CON_ACTIVE;

handle_send_dt_connection_ht_connected(cur_connection_node->origin, cur_connection_node->id);

return(0);
}

Expand Down Expand Up @@ -730,6 +738,64 @@ int handle_message_dt_connection_ht_data(){
}


/******************************************************************************
*
* handle_message_dt_connection_ht_connected()
*
* Inputs: None, but we will leverage the global io struct.
* Outputs: 0 for success. -1 on fatal error. -2 on non-fatal error.
*
* Purpose: Handle the broker case where a connection has succeeded.
*
******************************************************************************/
int handle_message_dt_connection_ht_connected(){
struct connection_node *cur_connection_node;


if((cur_connection_node = connection_node_find(message->header_origin, message->header_id)) == NULL){

if(handle_send_dt_connection_ht_destroy(message->header_origin, message->header_id, 0) == -1){
report_error("handle_message_dt_connection(): handle_send_dt_connection_ht_destroy(%d, %d, 0): %s", message->header_origin, message->header_id, strerror(errno));
return(-1);
}
return(-2);
}

connection_node_socks_reply(cur_connection_node, 1);

return(0);
}


/******************************************************************************
*
* handle_message_dt_connection_ht_refused()
*
* Inputs: None, but we will leverage the global io struct.
* Outputs: 0 for success. -1 on fatal error. -2 on non-fatal error.
*
* Purpose: Handle the broker case where a connection was refused.
*
******************************************************************************/
int handle_message_dt_connection_ht_refused(){
struct connection_node *cur_connection_node;


if((cur_connection_node = connection_node_find(message->header_origin, message->header_id)) == NULL){

if(handle_send_dt_connection_ht_destroy(message->header_origin, message->header_id, 0) == -1){
report_error("handle_message_dt_connection(): handle_send_dt_connection_ht_destroy(%d, %d, 0): %s", message->header_origin, message->header_id, strerror(errno));
return(-1);
}
return(-2);
}

connection_node_socks_reply(cur_connection_node, 0);

return(0);
}


/******************************************************************************
*
* handle_proxy_read()
Expand Down Expand Up @@ -995,32 +1061,24 @@ int handle_connection_socks_init(struct connection_node *cur_connection_node){
if(new_state == CON_SOCKS_V5_AUTH){
reply_buff = SOCKS_V5_AUTH_REPLY;
reply_buff_len = SOCKS_V5_AUTH_REPLY_LEN;
}else if(new_state == CON_ACTIVE){
if(cur_connection_node->state == CON_SOCKS_INIT){
reply_buff = SOCKS_V4_REPLY;
reply_buff_len = SOCKS_V4_REPLY_LEN;
}else if(cur_connection_node->state == CON_SOCKS_V5_AUTH){
reply_buff = SOCKS_V5_REPLY;
reply_buff_len = SOCKS_V5_REPLY_LEN;
}
}

retval = write(cur_connection_node->fd, reply_buff, reply_buff_len);
retval = write(cur_connection_node->fd, reply_buff, reply_buff_len);

if(retval == -1){
report_error("handle_connection_socks_init(): write(%d, %lx, %d): %s", cur_connection_node->fd, (unsigned long) reply_buff, reply_buff_len, strerror(errno));
return(-1);
}

if(retval != reply_buff_len){
report_error("handle_connection_socks_init(): write(%d, %lx, %d): Unable to send SOCKS reply.", cur_connection_node->fd, (unsigned long) reply_buff, reply_buff_len);
if(handle_send_dt_connection_ht_destroy(cur_connection_node->origin, cur_connection_node->id, 0) == -1){
report_error("handle_connection_socks_init(): handle_send_dt_connection_ht_destroy(%d, %d, 0): %s", cur_connection_node->origin, cur_connection_node->id, strerror(errno));
if(retval == -1){
report_error("handle_connection_socks_init(): write(%d, %lx, %d): %s", cur_connection_node->fd, (unsigned long) reply_buff, reply_buff_len, strerror(errno));
return(-1);
}
connection_node_delete(cur_connection_node);

if(retval != reply_buff_len){
report_error("handle_connection_socks_init(): write(%d, %lx, %d): Unable to send SOCKS reply.", cur_connection_node->fd, (unsigned long) reply_buff, reply_buff_len);
if(handle_send_dt_connection_ht_destroy(cur_connection_node->origin, cur_connection_node->id, 0) == -1){
report_error("handle_connection_socks_init(): handle_send_dt_connection_ht_destroy(%d, %d, 0): %s", cur_connection_node->origin, cur_connection_node->id, strerror(errno));
return(-1);
}
connection_node_delete(cur_connection_node);
}
}


cur_connection_node->state = new_state;

// Handle the case where we have a rude client that doesn't wait for data and just fills our buffer with both halves of the
Expand Down Expand Up @@ -1179,7 +1237,6 @@ int handle_send_dt_proxy_ht_report(struct proxy_node *cur_proxy_node){
return(0);
}


/******************************************************************************
*
* handle_send_dt_connection_ht_destroy()
Expand Down Expand Up @@ -1242,6 +1299,7 @@ int handle_send_dt_connection_ht_create(struct connection_node *cur_connection_n
message->header_origin = cur_connection_node->origin;
message->header_id = cur_connection_node->id;
message->header_proxy_type = cur_connection_node->proxy_type;
message->header_socks_type = cur_connection_node->socks_type;

memset(message->data, 0, io->message_data_size);
count = strlen(cur_connection_node->rhost_rport);
Expand Down Expand Up @@ -1288,6 +1346,68 @@ int handle_send_dt_nop(){
}


/******************************************************************************
*
* handle_send_dt_connection_ht_connected()
*
* Inputs: The origin and id tuple that identify the related connection.
* We will also leverage the global io struct.
* Outputs: 0 for success. -1 on fatal error.
*
* Purpose: Handle the broker case where we need to notify the remote node
* that a connection has been successfully connected.
*
******************************************************************************/
int handle_send_dt_connection_ht_connected(unsigned short origin, unsigned short id){

int retval;

message->data_type = DT_CONNECTION;
message->header_type = DT_CONNECTION_HT_CONNECTED;
message->header_origin = origin;
message->header_id = id;
message->data_len = 0;

if((retval = message_push()) == -1){
report_error("handle_send_dt_connection_ht_connected(): message_push(): %s", strerror(errno));
return(-1);
}

return(0);
}


/******************************************************************************
*
* handle_send_dt_connection_ht_refused()
*
* Inputs: The origin and id tuple that identify the related connection.
* We will also leverage the global io struct.
* Outputs: 0 for success. -1 on fatal error.
*
* Purpose: Handle the broker case where we need to notify the remote node
* that a connection has been refused.
*
******************************************************************************/
int handle_send_dt_connection_ht_refused(unsigned short origin, unsigned short id){

int retval;

message->data_type = DT_CONNECTION;
message->header_type = DT_CONNECTION_HT_REFUSED;
message->header_origin = origin;
message->header_id = id;
message->data_len = 0;

if((retval = message_push()) == -1){
report_error("handle_send_dt_connection_ht_refused(): message_push(): %s", strerror(errno));
return(-1);
}

return(0);
}


/******************************************************************************
*
* handle_tun_tap_init()
Expand Down
3 changes: 3 additions & 0 deletions helper_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ struct message_helper {
// Proxy types are defined in the protocol.h file.
unsigned short header_proxy_type;

unsigned short header_socks_type;

char *data;

struct message_helper *next;
Expand Down Expand Up @@ -122,6 +124,7 @@ struct connection_node {
unsigned short origin;
unsigned short id;
unsigned short proxy_type;
unsigned short socks_type;
int fd;

// A copy of the original rhost_rport string in the related proxy_node struct, to simplify retry requests.
Expand Down
14 changes: 14 additions & 0 deletions message.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ int message_push(){
header_len += sizeof(message->header_type) + sizeof(message->header_origin) + sizeof(message->header_id);
if(message->header_type == DT_PROXY_HT_CREATE || message->header_type == DT_PROXY_HT_REPORT || message->header_type == DT_CONNECTION_HT_CREATE){
header_len += sizeof(message->header_proxy_type);
header_len += sizeof(message->header_socks_type);
}
}

Expand Down Expand Up @@ -92,6 +93,12 @@ int message_push(){
(unsigned long) &tmp_short, (int) sizeof(tmp_short), strerror(errno));
return(-1);
}
tmp_short = htons(message->header_socks_type);
if(io->remote_write(&tmp_short, sizeof(tmp_short)) == -1){
report_error("message_push(): remote_write(%lx, %d): %s", \
(unsigned long) &tmp_short, (int) sizeof(tmp_short), strerror(errno));
return(-1);
}
}
}

Expand Down Expand Up @@ -188,6 +195,13 @@ int message_pull(){
}
message->header_proxy_type = ntohs(message->header_proxy_type);
header_len -= sizeof(message->header_proxy_type);
if((retval = io->remote_read(&message->header_socks_type, sizeof(message->header_socks_type))) == -1){
report_error("message_pull(): remote_read(%lx, %d): %s", \
(unsigned long) &message->header_socks_type, (int) sizeof(message->header_socks_type), strerror(errno));
return(-1);
}
message->header_socks_type = ntohs(message->header_socks_type);
header_len -= sizeof(message->header_socks_type);
}
}

Expand Down
4 changes: 3 additions & 1 deletion protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/

#define PROTOCOL_MAJOR_VERSION 1
#define PROTOCOL_MINOR_VERSION 0
#define PROTOCOL_MINOR_VERSION 1

/**********************************************************************************************************************
*
Expand Down Expand Up @@ -167,6 +167,8 @@
// As such, this reporting is typically handled as a best effort without guarantee of delivery.
#define DT_ERROR 6

#define DT_CONNECTION_HT_CONNECTED 7
#define DT_CONNECTION_HT_REFUSED 8
/*
* Other protocol constants used in messaging.
*/
Expand Down
Loading