|
@@ -14,7 +14,10 @@
|
|
|
#include <unistd.h>
|
|
|
#include <pthread.h>
|
|
|
#include <netinet/in.h>
|
|
|
-#include "SpBase.h"
|
|
|
+#include <string.h>
|
|
|
+#include <arpa/inet.h>
|
|
|
+//#include "winpr/winsock.h"
|
|
|
+//#include "winpr/file.h"
|
|
|
#endif
|
|
|
|
|
|
#include <stdlib.h>
|
|
@@ -42,6 +45,8 @@
|
|
|
#define KEY_LEN 16
|
|
|
|
|
|
#ifndef RVC_OS_WIN
|
|
|
+#include "SpBase.h"
|
|
|
+
|
|
|
typedef int SOCKET;
|
|
|
|
|
|
#ifndef INVALID_SOCKET
|
|
@@ -50,6 +55,17 @@ typedef int SOCKET;
|
|
|
#ifndef SOCKET_ERROR
|
|
|
#define SOCKET_ERROR (-1)
|
|
|
#endif
|
|
|
+
|
|
|
+#define max(a,b) (((a) > (b)) ? (a) : (b))
|
|
|
+#define min(a,b) (((a) < (b)) ? (a) : (b))
|
|
|
+
|
|
|
+unsigned long GetTickCount()
|
|
|
+{
|
|
|
+ struct timespec ts;
|
|
|
+ clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
|
+ return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
|
|
|
+}
|
|
|
+
|
|
|
#endif
|
|
|
|
|
|
typedef struct recv_info_t {
|
|
@@ -214,14 +230,24 @@ BIZCHAN_API(int) bizchan_lib_term()
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-static int config_copy(const bizchan_config_t *src, bizchan_config_t *dst)
|
|
|
+static int config_copy(bizchan_t* chan, const bizchan_config_t *src, bizchan_config_t *dst)
|
|
|
{
|
|
|
memcpy(dst, src, sizeof(bizchan_config_t));
|
|
|
- dst->proxy_server = _strdup(src->proxy_server);
|
|
|
- dst->bak_proxy_server = _strdup(src->bak_proxy_server);
|
|
|
- dst->session_id = _strdup(src->session_id);
|
|
|
- dst->agent_id = _strdup(src->agent_id);
|
|
|
- dst->client_id = _strdup(src->client_id);
|
|
|
+ dst->proxy_server = strdup(src->proxy_server);
|
|
|
+
|
|
|
+ if (src->bak_proxy_server != NULL) {
|
|
|
+ dst->bak_proxy_server = strdup(src->bak_proxy_server);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (src->session_id != NULL) {
|
|
|
+ dst->session_id = strdup(src->session_id);
|
|
|
+ }
|
|
|
+ if (src->agent_id != NULL) {
|
|
|
+ dst->agent_id = strdup(src->agent_id);
|
|
|
+ }
|
|
|
+ if (src->client_id != NULL) {
|
|
|
+ dst->client_id = strdup(src->client_id);
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -463,9 +489,9 @@ static int on_recv(bizchan_t *chan, SOCKET conn)
|
|
|
free(dec_buf);
|
|
|
} else {
|
|
|
if (hdr->compress) {
|
|
|
- int len = (int)qlz_size_decompressed(&hdr->data[0]);
|
|
|
+ int len = (int)qlz_size_decompressed((const char *)&hdr->data[0]);
|
|
|
char *unzip_buf = (char*)malloc(len);
|
|
|
- len = qlz_decompress(&hdr->data[0], unzip_buf, &ri->decompress_state);
|
|
|
+ len = qlz_decompress((const char*)&hdr->data[0], unzip_buf, &ri->decompress_state);
|
|
|
if (check_hash(unzip_buf, len, hdr->hash)) {
|
|
|
invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
|
|
|
} else {
|
|
@@ -473,8 +499,8 @@ static int on_recv(bizchan_t *chan, SOCKET conn)
|
|
|
}
|
|
|
free(unzip_buf);
|
|
|
} else {
|
|
|
- if (check_hash(&hdr->data[0], hdr->length, hdr->hash)) {
|
|
|
- invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, &hdr->data[0], hdr->length);
|
|
|
+ if (check_hash((char*)&hdr->data[0], hdr->length, hdr->hash)) {
|
|
|
+ invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, (const char*)&hdr->data[0], hdr->length);
|
|
|
} else {
|
|
|
OutputDebugStringA("pkt hash failed!\n");
|
|
|
}
|
|
@@ -491,7 +517,7 @@ static int on_recv(bizchan_t *chan, SOCKET conn)
|
|
|
ri->offset -= i;
|
|
|
if (ri->offset == ri->buf_len) { // double large
|
|
|
ri->buf_len = 2 * ri->buf_len;
|
|
|
- ri->buf = realloc(ri->buf, ri->buf_len);
|
|
|
+ ri->buf = (char *)realloc(ri->buf, ri->buf_len);
|
|
|
}
|
|
|
}
|
|
|
} while (n > 0);
|
|
@@ -571,7 +597,6 @@ static int prepare_socket(SOCKET s, HANDLE evt)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
static void dump_exception(PEXCEPTION_POINTERS ExceptionInfo)
|
|
|
{
|
|
|
char tmp[MAX_PATH];
|
|
@@ -598,7 +623,7 @@ static void dump_exception(PEXCEPTION_POINTERS ExceptionInfo)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-#ifdef RVC_OS_WIN
|
|
|
+ #ifdef RVC_OS_WIN
|
|
|
static void process(bizchan_t *chan)
|
|
|
{
|
|
|
SOCKET conn = INVALID_SOCKET;
|
|
@@ -617,7 +642,7 @@ static void process(bizchan_t *chan)
|
|
|
conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
if (conn == INVALID_SOCKET)
|
|
|
goto on_error;
|
|
|
- rc = prepare_socket(chan, conn, evts[1]);
|
|
|
+ rc = prepare_socket(conn, evts[1]);
|
|
|
if (rc != 0)
|
|
|
goto on_error;
|
|
|
|
|
@@ -632,7 +657,7 @@ static void process(bizchan_t *chan)
|
|
|
if (conn == INVALID_SOCKET)
|
|
|
goto on_error;
|
|
|
WSAResetEvent(evts[1]);
|
|
|
- rc = prepare_socket(chan, conn, evts[1]);
|
|
|
+ rc = prepare_socket(conn, evts[1]);
|
|
|
if (rc != 0)
|
|
|
goto on_error;
|
|
|
addr.sin_port = htons(chan->config.bak_proxy_server_port);
|
|
@@ -826,7 +851,7 @@ on_error:
|
|
|
|
|
|
#else
|
|
|
|
|
|
-void do_shake_send(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
+static void do_shake_send(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
proxy_hdr hdr = { 0 };
|
|
|
proxy_ack_hdr ack_hdr;
|
|
|
int ack_hdr_recv_bytes = 0;
|
|
@@ -864,7 +889,7 @@ void do_shake_send(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
+static void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
int t;
|
|
|
proxy_ack_hdr ack_hdr;
|
|
|
int ack_hdr_recv_bytes = 0;
|
|
@@ -905,7 +930,7 @@ void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-int build_fd_sets(SOCKET conn, int evt, fd_set* read_fds, fd_set* write_fds, fd_set* except_fds)
|
|
|
+static void build_fd_sets(SOCKET conn, int evt, fd_set* read_fds, fd_set* write_fds, fd_set* except_fds)
|
|
|
{
|
|
|
FD_ZERO(read_fds);
|
|
|
FD_SET(conn, read_fds);
|
|
@@ -914,56 +939,60 @@ int build_fd_sets(SOCKET conn, int evt, fd_set* read_fds, fd_set* write_fds, fd_
|
|
|
FD_SET(conn, write_fds);
|
|
|
FD_ZERO(except_fds);
|
|
|
FD_SET(conn, except_fds);
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
-SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
|
|
|
-{
|
|
|
- SOCKET m_hSocket;
|
|
|
- struct sockaddr_in addrSrv = { 0 };
|
|
|
- fd_set writeset;
|
|
|
- char buffer[128];
|
|
|
-
|
|
|
- chan->cb.dbg(chan, 0, "processLinux connect_server 1", chan->cb.user_data);
|
|
|
- m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
- if (m_hSocket == INVALID_SOCKET)
|
|
|
- return INVALID_SOCKET;
|
|
|
-
|
|
|
- chan->cb.dbg(chan, 0, "processLinux connect_server 2", chan->cb.user_data);
|
|
|
+static int set_socket_noblock(SOCKET socket) {
|
|
|
#ifdef RVC_OS_WIN
|
|
|
{
|
|
|
//windows将socket设置成非阻塞的方式
|
|
|
unsigned long on = 1;
|
|
|
- if (ioctlsocket(m_hSocket, FIONBIO, &on) < 0) {
|
|
|
- closesocket(m_hSocket);
|
|
|
- return INVALID_SOCKET;
|
|
|
+ if (ioctlsocket(socket, FIONBIO, &on) < 0) {
|
|
|
+ return -1;
|
|
|
}
|
|
|
}
|
|
|
#else
|
|
|
{
|
|
|
//linux将socket设置成非阻塞的方式
|
|
|
//将新socket设置为non-blocking
|
|
|
- /*int oldflag = fcntl(m_hSocket, F_GETFL, 0);
|
|
|
+ int oldflag = fcntl(socket, F_GETFL, 0);
|
|
|
int newflag = oldflag | O_NONBLOCK;
|
|
|
- if (fcntl(m_hSocket, F_SETFL, newflag) == -1) {
|
|
|
- close(m_hSocket);
|
|
|
- return INVALID_SOCKET;
|
|
|
- }*/
|
|
|
+ if (fcntl(socket, F_SETFL, newflag) == -1) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
}
|
|
|
#endif
|
|
|
- snprint(buffer, 128, "server:%s , port:%d", server, port);
|
|
|
- chan->cb.dbg(chan, 0, "processLinux connect_server 3", chan->cb.user_data);
|
|
|
- chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
|
|
|
+{
|
|
|
+ SOCKET m_hSocket;
|
|
|
+ struct sockaddr_in addrSrv = { 0 };
|
|
|
+ //fd_set writeset;
|
|
|
+
|
|
|
+ m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
+ if (m_hSocket == INVALID_SOCKET)
|
|
|
+ return INVALID_SOCKET;
|
|
|
+
|
|
|
addrSrv.sin_family = AF_INET;
|
|
|
addrSrv.sin_addr.s_addr = inet_addr(server);
|
|
|
- addrSrv.sin_port = htons((u_short)port);
|
|
|
+ addrSrv.sin_port = htons(port);
|
|
|
int ret = connect(m_hSocket, (struct sockaddr*)&addrSrv, sizeof(addrSrv));
|
|
|
if (ret == 0) {
|
|
|
- chan->cb.dbg(chan, 0, "connect_server success1", chan->cb.user_data);
|
|
|
return m_hSocket;
|
|
|
}
|
|
|
+ else {
|
|
|
+ chan->cb.dbg(chan, 0, "connect_server failed", chan->cb.user_data);
|
|
|
+#ifdef RVC_OS_WIN
|
|
|
+ closesocket(m_hSocket);
|
|
|
+#else
|
|
|
+ close(m_hSocket);
|
|
|
+#endif
|
|
|
+ return INVALID_SOCKET;
|
|
|
+ }
|
|
|
|
|
|
- chan->cb.dbg(chan, 0, "processLinux connect_server 4", chan->cb.user_data);
|
|
|
+/*
|
|
|
#ifdef RVC_OS_WIN
|
|
|
//windows下检测WSAEWOULDBLOCK
|
|
|
if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) {
|
|
@@ -995,67 +1024,43 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
|
|
|
return INVALID_SOCKET;
|
|
|
}
|
|
|
|
|
|
- return m_hSocket;
|
|
|
+ return m_hSocket;*/
|
|
|
}
|
|
|
|
|
|
-static void processLinux(bizchan_t* chan) {
|
|
|
+static void process(bizchan_t* chan) {
|
|
|
int error = 0;
|
|
|
SOCKET conn = connect_server(chan, chan->config.proxy_server, chan->config.proxy_server_port, 5);
|
|
|
if (conn == INVALID_SOCKET && chan->config.bak_proxy_server && strlen(chan->config.bak_proxy_server)) { // try connect to back proxy server
|
|
|
conn = connect_server(chan, chan->config.bak_proxy_server, chan->config.bak_proxy_server_port, 5);
|
|
|
}
|
|
|
- chan->cb.dbg(chan, 0, "connect_server success", chan->cb.user_data);
|
|
|
|
|
|
if (conn == INVALID_SOCKET) {
|
|
|
error = -1;
|
|
|
}
|
|
|
else {
|
|
|
- fd_set read_fds;
|
|
|
- fd_set write_fds;
|
|
|
- fd_set except_fds;
|
|
|
- int maxfd = max(conn, chan->evt[0]);
|
|
|
- while (!chan->stop_flag && !chan->connected) {
|
|
|
- struct timeval tv;
|
|
|
- tv.tv_sec = MAX_TIMEOUT / 1000;
|
|
|
- //可以利用tv_usec做更小精度的超时设置
|
|
|
- tv.tv_usec = 0;
|
|
|
- // Select() updates fd_set's, so we need to build fd_set's before each select()call.
|
|
|
- build_fd_sets(conn, chan->evt[0], &read_fds, &write_fds, &except_fds);
|
|
|
- chan->cb.dbg(chan, 0, "processLinux select start", chan->cb.user_data);
|
|
|
- int activity = select(maxfd + 1, &read_fds, &write_fds, &except_fds, &tv);
|
|
|
- switch (activity) {
|
|
|
- case -1:
|
|
|
- perror("select()");
|
|
|
- chan->cb.dbg(chan, 0, "processLinux select -1", chan->cb.user_data);
|
|
|
- goto on_error;
|
|
|
- case 0:
|
|
|
- // timeout
|
|
|
- printf("select() returns 0.\n");
|
|
|
- chan->cb.dbg(chan, 0, "processLinux select 0", chan->cb.user_data);
|
|
|
- goto on_error;
|
|
|
- default:
|
|
|
- /* All fd_set's should be checked. */
|
|
|
- if (FD_ISSET(conn, &read_fds)) {
|
|
|
- chan->cb.dbg(chan, 0, "processLinux do_shake_send ", chan->cb.user_data);
|
|
|
- do_shake_send(chan, conn, &error);
|
|
|
- }
|
|
|
- if (FD_ISSET(conn, &write_fds)) {
|
|
|
- chan->cb.dbg(chan, 0, "processLinux do_shake_recv ", chan->cb.user_data);
|
|
|
- do_shake_recv(chan, conn, &error);
|
|
|
- }
|
|
|
- if (FD_ISSET(conn, &except_fds)) {
|
|
|
- error = -1;
|
|
|
- }
|
|
|
- if (error != 0) {
|
|
|
- goto on_error;
|
|
|
- }
|
|
|
- }
|
|
|
+ do_shake_send(chan, conn, &error);
|
|
|
+ if (error != 0) {
|
|
|
+ goto on_error;
|
|
|
+ }
|
|
|
+ do_shake_recv(chan, conn, &error);
|
|
|
+ if (error != 0) {
|
|
|
+ goto on_error;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (chan->connected)
|
|
|
{
|
|
|
int rc;
|
|
|
+ fd_set read_fds;
|
|
|
+ fd_set write_fds;
|
|
|
+ fd_set except_fds;
|
|
|
+ int maxfd = max(conn, chan->evt[0]);
|
|
|
+ rc = set_socket_noblock(conn);
|
|
|
+ if (rc)
|
|
|
+ {
|
|
|
+ on_close(chan);
|
|
|
+ goto on_error;
|
|
|
+ }
|
|
|
invoke_on_connect(chan, 0);
|
|
|
chan->recv_info.offset = 0;
|
|
|
rc = on_recv(chan, conn);
|
|
@@ -1097,12 +1102,12 @@ static void processLinux(bizchan_t* chan) {
|
|
|
default: {
|
|
|
/* All fd_set's should be checked. */
|
|
|
if (FD_ISSET(conn, &read_fds)) {
|
|
|
- rc = on_send(chan, conn);
|
|
|
+ rc = on_recv(chan, conn);
|
|
|
if (rc != 0)
|
|
|
break;
|
|
|
}
|
|
|
if (FD_ISSET(conn, &write_fds)) {
|
|
|
- rc = on_recv(chan, conn);
|
|
|
+ rc = on_send(chan, conn);
|
|
|
if (rc != 0)
|
|
|
break;
|
|
|
}
|
|
@@ -1156,7 +1161,7 @@ static void* work_proc(void* arg)
|
|
|
}
|
|
|
#else
|
|
|
chan->cb.dbg(chan, 0, "work_proc start", chan->cb.user_data);
|
|
|
- processLinux(chan);
|
|
|
+ process(chan);
|
|
|
#endif
|
|
|
return 0;
|
|
|
}
|
|
@@ -1291,9 +1296,9 @@ BIZCHAN_API(int) bizchan_create(const bizchan_config_t *config, const bizchan_ca
|
|
|
chan->recv_info.buf = (char*)malloc(chan->recv_info.buf_len);
|
|
|
if (!chan->recv_info.buf)
|
|
|
goto on_error;
|
|
|
- if (config_copy(config, &chan->config) != 0)
|
|
|
- goto on_error;
|
|
|
memcpy(&chan->cb, cb, sizeof(bizchan_callback_t));
|
|
|
+ if (config_copy(chan, config, &chan->config) != 0)
|
|
|
+ goto on_error;
|
|
|
ListEntry_InitHead(&chan->send_info.send_list);
|
|
|
#ifdef RVC_OS_WIN
|
|
|
InitializeCriticalSection(&chan->send_info.lock);
|
|
@@ -1485,7 +1490,7 @@ BIZCHAN_API(int) bizchan_post_pkt(bizchan_t *chan, int type, int compress, int e
|
|
|
|
|
|
if (!compress || pkt_size == 0) {
|
|
|
acm_hdr *hdr;
|
|
|
- t->buf = malloc(pkt_size + sizeof(acm_hdr));
|
|
|
+ t->buf = (char*)malloc(pkt_size + sizeof(acm_hdr));
|
|
|
t->left = pkt_size + sizeof(acm_hdr);
|
|
|
t->sended = 0;
|
|
|
hdr = (acm_hdr*)&t->buf[0];
|
|
@@ -1502,9 +1507,9 @@ BIZCHAN_API(int) bizchan_post_pkt(bizchan_t *chan, int type, int compress, int e
|
|
|
qlz_state_compress state_compress;
|
|
|
acm_hdr *hdr;
|
|
|
int new_pkt_size;
|
|
|
- t->buf = malloc(2*pkt_size + sizeof(acm_hdr) + 16);
|
|
|
+ t->buf = (char*)malloc(2*pkt_size + sizeof(acm_hdr) + 16);
|
|
|
hdr = (acm_hdr *)&t->buf[0];
|
|
|
- new_pkt_size = (int)qlz_compress(pkt, &hdr->data[0], pkt_size, &state_compress);
|
|
|
+ new_pkt_size = (int)qlz_compress(pkt, (char*)&hdr->data[0], pkt_size, &state_compress);
|
|
|
if (new_pkt_size < pkt_size) {
|
|
|
hdr->compress = 1;
|
|
|
hdr->length = new_pkt_size;
|
|
@@ -1545,7 +1550,7 @@ BIZCHAN_API(int) bizchan_post_pkt(bizchan_t *chan, int type, int compress, int e
|
|
|
BIZCHAN_API(int) bizchan_winsync_send(bizchan_t *chan, int sub_type, const void *buf, int size)
|
|
|
{
|
|
|
if (chan && chan->work_thread) {
|
|
|
- return bizchan_post_pkt(chan, ACM_TYPE_SYNC, 1, sub_type, 1, 0, buf, size);
|
|
|
+ return bizchan_post_pkt(chan, ACM_TYPE_SYNC, 1, sub_type, 1, 0, (const char*)buf, size);
|
|
|
} else {
|
|
|
return -1;
|
|
|
}
|