mirror of
https://github.com/lxsang/antd-tunnel-plugin
synced 2024-11-16 01:38:22 +01:00
allow ping message on tunnel
This commit is contained in:
parent
61e7040426
commit
15e086441d
BIN
dist/tunnel-0.1.0b.tar.gz
vendored
BIN
dist/tunnel-0.1.0b.tar.gz
vendored
Binary file not shown.
98
tunnel.c
98
tunnel.c
@ -20,6 +20,8 @@
|
||||
#define HOT_LINE_SOCKET "antd_hotline.sock"
|
||||
#define SOCK_DIR_NAME "channels"
|
||||
|
||||
#define PING_INTERVAL 10u // 10s
|
||||
|
||||
#define MAX_CHANNEL_ID 65535u
|
||||
|
||||
#define MAX_CHANNEL_PATH (sizeof(__plugin__.tmpdir) + strlen(SOCK_DIR_NAME) + strlen(HOT_LINE_SOCKET) + 2)
|
||||
@ -35,21 +37,25 @@
|
||||
#define CHANNEL_CLOSE (uint8_t)0x5
|
||||
#define CHANNEL_DATA (uint8_t)0x6
|
||||
#define CHANNEL_CTRL (uint8_t)0x7
|
||||
#define TUNNEL_PING (uint8_t)0x8
|
||||
//#define CHANNEL_LIST (uint8_t)0x7
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
int sock;
|
||||
char name[MAX_CHANNEL_NAME];
|
||||
bst_node_t *subscribers;
|
||||
} antd_tunnel_channel_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type;
|
||||
uint16_t channel_id;
|
||||
uint16_t client_id;
|
||||
uint16_t size;
|
||||
} antd_tunnel_msg_h_t;
|
||||
|
||||
typedef struct{
|
||||
typedef struct
|
||||
{
|
||||
antd_tunnel_msg_h_t header;
|
||||
uint8_t *data;
|
||||
} antd_tunnel_msg_t;
|
||||
@ -58,7 +64,8 @@ typedef struct{
|
||||
* |BEGIN MAGIC(2)|MSG TYPE(1)| CHANNEL ID (2)| CLIENT ID (2)| data length (2)| data(m) | END MAGIC(2)|
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
pthread_mutex_t lock;
|
||||
bst_node_t *channels;
|
||||
pthread_t tid;
|
||||
@ -69,7 +76,6 @@ typedef struct {
|
||||
|
||||
static antd_tunnel_t g_tunnel;
|
||||
|
||||
|
||||
static int mk_socket(const char *name, char *path)
|
||||
{
|
||||
struct sockaddr_un address;
|
||||
@ -95,7 +101,6 @@ static int mk_socket(const char* name, char* path)
|
||||
}
|
||||
(void)strcat(path, name);
|
||||
|
||||
|
||||
(void)strncpy(address.sun_path, path, sizeof(address.sun_path));
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1)
|
||||
@ -197,7 +202,7 @@ static int msg_read(int fd, antd_tunnel_msg_t* msg)
|
||||
ERROR("Unable to read msg type: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(msg->header.type > 0x6)
|
||||
if (msg->header.type > 0x8)
|
||||
{
|
||||
ERROR("Unknown msg type: %d", msg->header.type);
|
||||
return -1;
|
||||
@ -279,11 +284,12 @@ static int msg_write(int fd, antd_tunnel_msg_t* msg)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static void write_msg_to_client(antd_tunnel_msg_t* msg, antd_client_t* client)
|
||||
static int write_msg_to_client(antd_tunnel_msg_t *msg, antd_client_t *client)
|
||||
{
|
||||
uint8_t *buffer;
|
||||
uint16_t u16 = 0;
|
||||
int offset = 0;
|
||||
int ret;
|
||||
buffer = (uint8_t *)malloc(msg->header.size +
|
||||
sizeof((int)MSG_MAGIC_BEGIN) +
|
||||
sizeof(msg->header.type) +
|
||||
@ -294,7 +300,7 @@ static void write_msg_to_client(antd_tunnel_msg_t* msg, antd_client_t* client)
|
||||
if (buffer == NULL)
|
||||
{
|
||||
ERROR("unable to allocate memory for write");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
// magic
|
||||
u16 = MSG_MAGIC_BEGIN;
|
||||
@ -322,10 +328,10 @@ static void write_msg_to_client(antd_tunnel_msg_t* msg, antd_client_t* client)
|
||||
offset += sizeof(u16);
|
||||
|
||||
// write it to the websocket
|
||||
ws_b(client,buffer, offset);
|
||||
ret = ws_b(client, buffer, offset);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static void unsubscribe(bst_node_t *node, void **argv, int argc)
|
||||
{
|
||||
@ -340,7 +346,10 @@ static void unsubscribe(bst_node_t* node, void** argv, int argc)
|
||||
msg.header.type = CHANNEL_UNSUBSCRIBE;
|
||||
msg.header.size = 0;
|
||||
msg.data = NULL;
|
||||
write_msg_to_client(&msg,(antd_client_t*)node->data);
|
||||
if (write_msg_to_client(&msg, (antd_client_t *)node->data) != 0)
|
||||
{
|
||||
ERROR("Unable to send unsubscribe message to client");
|
||||
}
|
||||
}
|
||||
}
|
||||
static void destroy_channel(antd_tunnel_channel_t *channel)
|
||||
@ -551,7 +560,10 @@ static void handle_channel(bst_node_t* node, void** args, int argc)
|
||||
rq = (antd_client_t *)client->data;
|
||||
if (rq != NULL)
|
||||
{
|
||||
write_msg_to_client(&msg, rq);
|
||||
if (write_msg_to_client(&msg, rq) != 0)
|
||||
{
|
||||
ERROR("Unable to send CTRL command to client");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -737,7 +749,10 @@ static void process_client_message(antd_tunnel_msg_t* msg, antd_client_t* client
|
||||
msg->header.size = strlen(buff);
|
||||
msg->data = (uint8_t *)buff;
|
||||
ERROR("%s", buff);
|
||||
write_msg_to_client(msg, client);
|
||||
if (write_msg_to_client(msg, client) != 0)
|
||||
{
|
||||
ERROR("Unable to send error message to client");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (msg->header.size > 0)
|
||||
@ -767,7 +782,10 @@ static void process_client_message(antd_tunnel_msg_t* msg, antd_client_t* client
|
||||
msg->header.size = sizeof(g_tunnel.id_allocator);
|
||||
(void)memcpy(buff, &g_tunnel.id_allocator, sizeof(g_tunnel.id_allocator));
|
||||
msg->data = (uint8_t *)buff;
|
||||
write_msg_to_client(msg, client);
|
||||
if (write_msg_to_client(msg, client) != 0)
|
||||
{
|
||||
ERROR("Unable to send subscribe OK message to client");
|
||||
}
|
||||
msg->header.client_id = g_tunnel.id_allocator;
|
||||
msg->header.type = CHANNEL_SUBSCRIBE;
|
||||
}
|
||||
@ -777,7 +795,10 @@ static void process_client_message(antd_tunnel_msg_t* msg, antd_client_t* client
|
||||
msg->header.type = CHANNEL_OK;
|
||||
msg->header.channel_id = hash_val;
|
||||
msg->header.size = 0;
|
||||
write_msg_to_client(msg, client);
|
||||
if (write_msg_to_client(msg, client) != 0)
|
||||
{
|
||||
ERROR("Unable to send unsubscribe OK message to client");
|
||||
}
|
||||
msg->header.type = CHANNEL_UNSUBSCRIBE;
|
||||
}
|
||||
// forward to publisher
|
||||
@ -797,7 +818,10 @@ static void process_client_message(antd_tunnel_msg_t* msg, antd_client_t* client
|
||||
if (msg->header.type == CHANNEL_SUBSCRIBE)
|
||||
{
|
||||
msg->header.type = CHANNEL_ERROR;
|
||||
write_msg_to_client(msg, client);
|
||||
if (write_msg_to_client(msg, client) != 0)
|
||||
{
|
||||
ERROR("Unable to send channel not found error to client");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -857,12 +881,12 @@ static void unsubscribe_notify(bst_node_t* node, void** argv, int argc)
|
||||
}
|
||||
}
|
||||
list_free(&list);
|
||||
|
||||
}
|
||||
|
||||
void *handle(void *rq_data)
|
||||
{
|
||||
antd_request_t *rq = (antd_request_t *)rq_data;
|
||||
antd_client_t *client = ((antd_client_t *)(rq->client));
|
||||
antd_task_t *task = antd_create_task(NULL, (void *)rq, NULL, time(NULL));
|
||||
ws_msg_header_t *h = NULL;
|
||||
antd_tunnel_msg_t msg;
|
||||
@ -882,15 +906,20 @@ void *handle(void *rq_data)
|
||||
}
|
||||
if (ws_enable(rq->request))
|
||||
{
|
||||
argv[0] = (void *)rq->client;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500; // 5 ms
|
||||
FD_ZERO(&fd_in);
|
||||
FD_SET(((antd_client_t*)(rq->client))->sock, &fd_in);
|
||||
status = select(((antd_client_t*)(rq->client))->sock + 1, &fd_in, NULL, NULL, &timeout);
|
||||
FD_SET(client->sock, &fd_in);
|
||||
|
||||
status = select(client->sock + 1, &fd_in, NULL, NULL, &timeout);
|
||||
switch (status)
|
||||
{
|
||||
case -1:
|
||||
LOG("Error %d on select()\n", errno);
|
||||
pthread_mutex_lock(&g_tunnel.lock);
|
||||
bst_for_each(g_tunnel.channels, unsubscribe_notify, argv, 1);
|
||||
pthread_mutex_unlock(&g_tunnel.lock);
|
||||
return task;
|
||||
break;
|
||||
case 0:
|
||||
@ -899,7 +928,6 @@ void *handle(void *rq_data)
|
||||
select(0, NULL, NULL, NULL, &timeout);
|
||||
break;
|
||||
default:
|
||||
argv[0] = (void*) rq->client;
|
||||
pthread_mutex_lock(&g_tunnel.lock);
|
||||
h = ws_read_header(rq->client);
|
||||
pthread_mutex_unlock(&g_tunnel.lock);
|
||||
@ -920,7 +948,6 @@ void *handle(void *rq_data)
|
||||
{
|
||||
LOG("Websocket: connection closed");
|
||||
pthread_mutex_lock(&g_tunnel.lock);
|
||||
//ws_close(rq->client, 1011);
|
||||
bst_for_each(g_tunnel.channels, unsubscribe_notify, argv, 1);
|
||||
pthread_mutex_unlock(&g_tunnel.lock);
|
||||
free(h);
|
||||
@ -947,6 +974,9 @@ void *handle(void *rq_data)
|
||||
ERROR("Invalid begin magic number: %d, expected %d", u16, MSG_MAGIC_BEGIN);
|
||||
free(buffer);
|
||||
free(h);
|
||||
pthread_mutex_lock(&g_tunnel.lock);
|
||||
bst_for_each(g_tunnel.channels, unsubscribe_notify, argv, 1);
|
||||
pthread_mutex_unlock(&g_tunnel.lock);
|
||||
return task;
|
||||
}
|
||||
// msgtype
|
||||
@ -977,6 +1007,9 @@ void *handle(void *rq_data)
|
||||
ERROR("Invalid end magic number: %d, expected %d", u16, MSG_MAGIC_END);
|
||||
free(buffer);
|
||||
free(h);
|
||||
pthread_mutex_lock(&g_tunnel.lock);
|
||||
bst_for_each(g_tunnel.channels, unsubscribe_notify, argv, 1);
|
||||
pthread_mutex_unlock(&g_tunnel.lock);
|
||||
return task;
|
||||
}
|
||||
|
||||
@ -1001,6 +1034,27 @@ void *handle(void *rq_data)
|
||||
free(h);
|
||||
}
|
||||
}
|
||||
// check whether we need to send ping message to client
|
||||
if (difftime(time(NULL), client->last_io) > (double)PING_INTERVAL)
|
||||
{
|
||||
// send message to client
|
||||
msg.header.type = TUNNEL_PING;
|
||||
msg.header.client_id = 0;
|
||||
msg.header.channel_id = 0;
|
||||
msg.header.size = 0;
|
||||
msg.data = NULL;
|
||||
|
||||
if (write_msg_to_client(&msg, client) != 0)
|
||||
{
|
||||
// close the connection
|
||||
pthread_mutex_lock(&g_tunnel.lock);
|
||||
//ws_close(rq->client, 1011);
|
||||
bst_for_each(g_tunnel.channels, unsubscribe_notify, argv, 1);
|
||||
pthread_mutex_unlock(&g_tunnel.lock);
|
||||
ERROR("Unable to ping client, close the connection: %d", client->sock);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user