1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138 |
- #include "bizchan.h"
- #include "quicklz.h"
- #define WIN32_LEAN_AND_MEAN
- #include <Windows.h>
- #include <WinSock2.h>
- #include <WinSock.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <process.h>
- #include <assert.h>
- #include "chan_protocol.h"
- //#include "acmstrdec.h"
- //#include "acmstrenc.h"
- #include "openssl\rc4.h"
- #include "ListEntry.h"
- #include <screencodec.h>
- #include "jpeg2k.h"
- #include "chinaEncrypt.h"
- #include <DbgHelp.h>
- #pragma comment(lib, "dbghelp.lib")
- #define PING_INTERVAL 10000 // 10s
- #define MAX_TIMEOUT 60000 //超时时间60S,20170313修改,解决排队机闪呼的问题
- #define DEFAULT_RX_BUF_SIZE 8192
- #define KEY_LEN 16
- #define ENCRYPT_CHINA 1
- typedef struct recv_info_t {
- int offset;
- char *buf;
- int buf_len;
- char *unzip_buf;
- int unzip_len;
- qlz_state_decompress decompress_state;
- }recv_info_t;
- typedef struct send_buf_node {
- LIST_ENTRY entry;
- char *buf;
- int left;
- int sended;
- int need_encrypt;
- }send_buf_node;
- typedef struct send_info_t {
- //send_buf_node *send_list;
- LIST_ENTRY send_list;
- CRITICAL_SECTION lock;
- //qlz_state_compress compress_state;
- }send_info_t;
- typedef struct img_recv_t {
- char *data;
- int length;
- int offset;
- int id;
- }img_recv_t;
- struct bizchan_t
- {
- bizchan_config_t config;
- OnRecvPacket winsync_on_recv_cb;
- OnMode mode_cb;
- void *winsync_user_data;
- bizchan_callback_t cb;
- void *tag;
- HANDLE work_thread;
- HANDLE evt;
- volatile int stop_flag;
- recv_info_t recv_info;
- send_info_t send_info;
- int screen_img_id;
- int photo_img_id;
- int b_primary_server;
- int remote_video_rtp_port;
- int remote_video_desc;
- char remote_client_id[32];
- int connected;
- char local_pwd[KEY_LEN];
- char remote_pwd[KEY_LEN];
- RC4_KEY local_key;
- RC4_KEY remote_key;
- int remote_version;
- LARGE_INTEGER last_remote_active_time;
- LARGE_INTEGER last_local_active_time;
- screen_decoder_session_t *dec_session;
- };
- typedef int (*lpfn_cryptionfun)(unsigned char * out ,int outLen,const unsigned char * in,int inLen);
- static lpfn_cryptionfun decodestring = NULL;
- static lpfn_cryptionfun encodestring = NULL;
- static unsigned char seed_key []= {0x81,0x32,0x13,0xf5,0x29,0x3b,0x52,0x37,0x61,0x98,0x33,0x15,0x72,0x31,0xfe,0x34};
- static __inline unsigned int hash32_buf(const void *bf, size_t len, unsigned int hash)
- {
- const unsigned char *s = (const unsigned char*)bf;
- while (len-- != 0) /* "nemesi": k=257, r=r*257 */
- hash = hash * 257 + *s++;
- return (hash * 257);
- }
- static void generate_rand_key(char *key, int size)
- {
- int i;
- srand(GetTickCount()*33);
- for (i = 0; i < size; ++i) {
- key[i] = (char)(rand() & 0xff);
- }
- srand(GetCurrentProcessId() * 33);
- for (i = 0; i < size; ++i) {
- key[i] ^= (char)(rand() & 0xff);
- }
- }
- static __inline unsigned long hash_key(const char *key, int size)
- {
- return hash32_buf(key, size, 0);
- }
- static __inline int check_hash(char *key, int size, int hash_code)
- {
- return hash32_buf(key, size, 0) == hash_code;
- }
- static __inline void GetTick(LARGE_INTEGER *last, LARGE_INTEGER *lt)
- {
- DWORD dwNow = GetTickCount();
- if (last->LowPart > dwNow) {
- lt->LowPart = dwNow;
- lt->HighPart = last->HighPart + 1;
- } else {
- lt->LowPart = dwNow;
- lt->HighPart = last->HighPart;
- }
- }
- void bizlog(bizchan_t *chan, const char* fmt, ...)
- {
- if (chan){
- va_list arg;
- va_start(arg, fmt);
- if (chan->cb.dbg) {
- (*chan->cb.dbg)(chan->cb.user_data, fmt, arg);
- }
- va_end(arg);
- }
- }
- BIZCHAN_API(int) bizchan_lib_init()
- {
- WSADATA wsaData;
- return WSAStartup(0x0202, &wsaData);
- }
- BIZCHAN_API(int) bizchan_lib_term()
- {
- return WSACleanup();
- }
- static int config_copy(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);
- return 0;
- }
- static int config_check(const bizchan_config_t *config)
- {
- if (!config->proxy_server)
- return -1;
- if (config->proxy_server_port <= 0 || config->proxy_server_port >= 0xffff)
- return -1;
- if (config->bak_proxy_server) {
- if (config->bak_proxy_server_port <= 0 || config->bak_proxy_server_port >= 0xffff)
- return -1;
- }
- if (!config->session_id)
- return -1;
- if (!config->agent_id)
- return -1;
- return 0;
- }
- static void config_free(bizchan_config_t *config)
- {
- free(config->proxy_server);
- free(config->bak_proxy_server);
- free(config->session_id);
- free(config->agent_id);
- free(config->client_id);
- }
- static int callback_check(const bizchan_callback_t *cb)
- {
- if (!cb->on_close) {
- return -1;
- }
- if (!cb->on_connect) {
- return -1;
- }
-
- if (!cb->on_recv_pkt) {
- return -1;
- }
-
- return 0;
- }
- static void invoke_on_connect(bizchan_t *chan, int error)
- {
- if (error == 0) {
- chan->cb.on_connect(chan,
- error,
- chan->b_primary_server ? chan->config.proxy_server : chan->config.bak_proxy_server,
- chan->remote_video_rtp_port,
- chan->remote_video_desc,
- chan->remote_client_id,
- chan->cb.user_data);
- }
- else {
- chan->cb.on_connect(chan,
- error,
- NULL,
- 0,
- 0,
- NULL,
- chan->cb.user_data);
- }
- }
- //static FILE *rx_log_fp = NULL;
- static void invoke_on_recv_pkt(bizchan_t *chan, int type, int sub_type, int id, const char *pkt, int pkt_size)
- {
- /*if (rx_log_fp == NULL) {
- rx_log_fp = fopen("c:\\rxlog.txt", "wt");
- fprintf(rx_log_fp, "===================\n");
- }
- {
- SYSTEMTIME st;
- GetLocalTime(&st);
- fprintf(rx_log_fp, "[%02d:%02d:%02d.%03d] type = %d, sub_type = %d, id = %d, pkt_size = %d, hash = %d\n",
- st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
- type, sub_type, id, pkt_size, hash32_buf(pkt, pkt_size, 0));
- fflush(rx_log_fp);
- }*/
- //Dbg(chan, "invoke_on_recv_pkt, type:%d, sub_type:%d, id:%d, pkt_size:%d", type, sub_type, id, pkt_size);
- if (type == ACM_TYPE_SRN) {
- int cat = ACM_SRN_CAT(sub_type);
- if (cat == ACM_SRN_ANS) {
- if (id == chan->screen_img_id) {
- if (pkt_size == 4)
- {
- int err;
- memcpy(&err, pkt, 4);
- chan->cb.on_recv_screen(chan, id, err, 0, 0, NULL, 0, chan->cb.user_data);
- }
- else
- {
- int size = 0;
- int width, height;
- int rc;
- char *dec_buf = NULL;
- rc = screen_decoder_session_decode(chan->dec_session, pkt, pkt_size, &width, &height, dec_buf, &size);
- if (rc == 0) {
- dec_buf = (char*)malloc(size);
- rc = screen_decoder_session_decode(chan->dec_session, pkt, pkt_size, &width, &height, dec_buf, &size);
- }
- if (rc == 0) {
- chan->cb.on_recv_screen(chan, id, 0, width, height, dec_buf, size, chan->cb.user_data);
- } else {
- chan->cb.on_recv_screen(chan, id, rc, 0, 0, NULL, 0, chan->cb.user_data);
- }
- if (dec_buf)
- free(dec_buf);
- }
- }
- } else
- {
- chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
- }
- } else if (type == ACM_TYPE_PHT) {
- int cat = ACM_PHT_CAT(sub_type);
- if (cat == ACM_PHT_ANS)
- {
- if (id == chan->photo_img_id) {
- if (pkt_size == 4) {
- int err;
- memcpy(&err, pkt, 4);
- chan->cb.on_recv_photo(chan, id, err, 0, 0, NULL, 0, chan->cb.user_data);
- } else {
- jpeg2k_raw_image raw_image = {0};
- jpeg2k_coded_image codec_image = {0};
- int rc;
- codec_image.data = (unsigned char*)pkt;
- codec_image.len = pkt_size;
- rc = jpeg2k_decode(&raw_image, &codec_image);
- if (rc == 0) {
- chan->cb.on_recv_photo(chan, id, 0, raw_image.width, raw_image.height, (const char*)&raw_image.data[0], raw_image.len, chan->cb.user_data);
- jpeg2k_decode_free(&raw_image);
- } else {
- chan->cb.on_recv_photo(chan, id, rc, 0, 0, NULL, 0, chan->cb.user_data);
- }
- }
- }
- } else {
- chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
- }
- } else if (type == ACM_TYPE_SYNC) {
- if (chan->winsync_on_recv_cb) {
- chan->winsync_on_recv_cb(sub_type, pkt, pkt_size, chan->winsync_user_data);
- }
- //同时上报应用层,用于应用层判断采用哪种同步方式(Sivilight或者chrome H5)
- chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
-
- } else if (type == ACM_TYPE_MODE) {
- if (chan->mode_cb) {
- chan->mode_cb(TRUE, chan->winsync_user_data);
- }
- chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
- } else if (type == ACM_TYPE_PING) {
- //..... remote ping, nothing todo
- } else {
- chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
- }
- }
- static void invoke_on_close(bizchan_t *chan)
- {
- if (chan->cb.on_close) {
- chan->cb.on_close(chan, chan->cb.user_data);
- }
- }
- static void invoke_on_destroy(bizchan_t *chan)
- {
- if (chan->cb.on_destroy) {
- chan->cb.on_destroy(chan, chan->cb.user_data);
- }
- }
- static FILE *fp = NULL;
- static int on_recv2(bizchan_t *chan, SOCKET conn)
- {
- int n;
- char buf[0x10000+sizeof(acm_hdr)];
- if (fp == NULL) {
- fp = fopen ("g:\\rx.dat", "wb");
- }
-
- do {
- n = recv(conn, buf, sizeof(buf), 0);
- if (n > 0) {
- fwrite(buf, 1, n, fp);
- fflush(fp);
- }
- } while (n > 0);
- return (n == 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
- }
- static int on_recv(bizchan_t *chan, SOCKET conn)
- {
- recv_info_t *ri = &chan->recv_info;
- int n;
- do {
- n = recv(conn, ri->buf+ri->offset, ri->buf_len-ri->offset, 0);
- if (n > 0) {
- int i = 0;
- ri->offset += n;
- GetTick(&chan->last_remote_active_time, &chan->last_remote_active_time);
- while (ri->offset-i >= sizeof(acm_hdr)) {
- acm_hdr *hdr = (acm_hdr*)&ri->buf[i];
- //Dbg(chan, "on_recv, i:%d offset:%d, recv_length:%d", i, ri->offset, n);
- //bizlog(chan, "on_recv, encrypt:%u, type:%u, sub_type:%u, length:%lu, compress:%u", hdr->encrypt, hdr->type, hdr->sub_type, hdr->length, hdr->compress);
- if (hdr->length == 0) {
- printf("broken");
- }
- if (ri->offset-i >= hdr->length+sizeof(acm_hdr)) {
- if (hdr->encrypt)
- {
- int dec_length = hdr->length;
- char *dec_buf = (char*)malloc(hdr->length);
- int sm4_dec_result = DecStrWithSM4_ECB(chan->remote_pwd, sizeof(chan->remote_pwd), (unsigned char*)(&hdr->data[0]), hdr->length, (unsigned char*)dec_buf, &dec_length);
- if (sm4_dec_result != 0){
- bizlog(chan, "DecStrWithSM4_ECB failed, type:%u, sub_type:%u, length:%lu", hdr->type, hdr->sub_type, hdr->length);
- RC4_set_key(&chan->remote_key, sizeof(chan->remote_pwd), (unsigned char*)chan->remote_pwd);
- RC4(&chan->remote_key, hdr->length, (const unsigned char*)(&hdr->data[0]), (unsigned char*)dec_buf);
- dec_length = hdr->length;
- }
- if (hdr->compress)
- {
- int len = (int)qlz_size_decompressed(dec_buf);
- char *unzip_buf = (char*)malloc(len);
- len = qlz_decompress(dec_buf, 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 {
- //OutputDebugStringA("pkt hash failed!\n");
- bizlog(chan, "encrypt compress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu, unzip:%d", hdr->type, hdr->sub_type, hdr->length, hdr->hash, len);
- }
- free(unzip_buf);
- } else {
- //sm4解密后hdr->length长度与内容长度不一致,采用dec_length变量
- if (check_hash(dec_buf, dec_length, hdr->hash)) {
- invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, dec_buf, dec_length);
- }
- else {
- //OutputDebugStringA("pkt hash failed!\n");
- bizlog(chan, "encrypt uncompress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu", hdr->type, hdr->sub_type, hdr->length, hdr->hash);
- }
- }
- free(dec_buf);
- }
- else
- {
- if (hdr->compress)
- {
- int len = (int)qlz_size_decompressed((const char*)&hdr->data[0]);
- char *unzip_buf = (char*)malloc(len);
- 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 {
- //OutputDebugStringA("pkt hash failed!\n");
- bizlog(chan, "compress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu, unzip:%d", hdr->type, hdr->sub_type, hdr->length, hdr->hash, len);
- }
- free(unzip_buf);
- }
- else
- {
- 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");
- bizlog(chan, "uncompress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu", hdr->type, hdr->sub_type, hdr->length, hdr->hash);
- }
- }
- }
- i += hdr->length+sizeof(acm_hdr);
- } else {
- break;
- }
- }
- if (i != ri->offset) {
- memmove(&ri->buf[0], &ri->buf[i], ri->offset-i);
- }
- ri->offset -= i;
- if (ri->offset == ri->buf_len) { // double large
- ri->buf_len = 2 * ri->buf_len;
- ri->buf = (char*)realloc(ri->buf, ri->buf_len);
- }
- }
- } while (n > 0);
- return (n == 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
- }
- static int on_send(bizchan_t *chan, SOCKET conn)
- {
- send_info_t *si = &chan->send_info;
- int n = 0;
- EnterCriticalSection(&si->lock);
- if (!ListEntry_IsEmpty(&si->send_list)) {
- do {
- send_buf_node *t = CONTAINING_RECORD(ListEntry_GetHead(&si->send_list), send_buf_node, entry);
- if (t->need_encrypt) {
- //SM4加密,密文会比明文长16字节
- int enc_length = t->left + sizeof(acm_hdr)+16;
- acm_hdr *hdr = (acm_hdr*)t->buf;
- char *enc_buf = (char*)malloc(t->left+sizeof(acm_hdr) + 16);
- //version为2代表支持国密,采用SM4加密
- if(chan->remote_version != 1){
- EncStrWithSM4_ECB(chan->local_pwd, sizeof(chan->local_pwd), (unsigned char*)(&hdr->data[0]), hdr->length, (unsigned char*)(enc_buf+sizeof(acm_hdr)), &enc_length);
- hdr->length = enc_length;
- t->left = enc_length + sizeof(acm_hdr);
- //Dbg(chan, "enc_length:%d", enc_length);
- }
- else {
- RC4_set_key(&chan->local_key, sizeof(chan->local_pwd), (unsigned char*)chan->local_pwd);
- RC4(&chan->local_key, t->left, (const unsigned char*)(&hdr->data[0]), (unsigned char*)(enc_buf+sizeof(acm_hdr)));
- }
- memcpy(enc_buf, hdr, sizeof(acm_hdr));
- free(t->buf);
- t->buf = enc_buf;
- t->need_encrypt = 0;
- }
- n = send(conn, t->buf+t->sended, t->left, 0);
- if (n > 0) {
- char tmp[32] = {0};
- _snprintf(tmp, 32, "send out %d bytes!\n", n);
- OutputDebugStringA(tmp);
- //Dbg(chan, tmp);
- t->left -= n;
- t->sended += n;
- if (t->left == 0) {
- ListEntry_DeleteNode(&t->entry);
- free(t->buf);
- free(t);
- }
- GetTick(&chan->last_local_active_time, &chan->last_local_active_time);
- }
- } while (n > 0 && !ListEntry_IsEmpty(&si->send_list));
- }
- LeaveCriticalSection(&si->lock);
- return (n >= 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
- }
- static void on_close(bizchan_t *chan)
- {
- invoke_on_close(chan);
- }
- static int prepare_socket(SOCKET s, HANDLE evt)
- {
- BOOL opt = TRUE;
- int rc;
- rc = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
- opt = TRUE;
- if (rc == 0)
- rc = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, (char*)&opt, sizeof(opt));
- if (rc == 0)
- rc = WSAEventSelect(s, evt, FD_CONNECT | FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE);
- return rc;
- }
- static void dump_exception(PEXCEPTION_POINTERS ExceptionInfo)
- {
- char tmp[MAX_PATH];
- HANDLE hDumpFile;
- sprintf(tmp, ".\\bizchan_%d.dmp", GetCurrentProcessId());
- hDumpFile = CreateFileA( tmp, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
- if( ( hDumpFile != NULL ) && ( hDumpFile != INVALID_HANDLE_VALUE ) )
- {
- MINIDUMP_EXCEPTION_INFORMATION mdei;
- MINIDUMP_TYPE mdt;
- mdei.ThreadId = GetCurrentThreadId();
- mdei.ExceptionPointers = ExceptionInfo;
- mdei.ClientPointers = FALSE;
- mdt = MiniDumpWithFullMemory;
- MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
- hDumpFile, mdt, (ExceptionInfo != 0) ? &mdei : 0, 0, 0 );
- CloseHandle( hDumpFile );
- }
- }
- static BOOL addr_is_domain(const char* pserver_addr)
- {
- BOOL bret = FALSE;
- if (NULL == pserver_addr){
- return bret;
- }
- if (strstr(pserver_addr, ".com") ||strstr(pserver_addr, ".cn")){
- bret = TRUE;
- }
- return bret;
- }
- static unsigned long biz_get_inetaddr(bizchan_t *chan, BOOL bprimary, const char* pserver)
- {
- unsigned long uret = 0;
- if (NULL == pserver){
- return uret;
- }
- uret = inet_addr(pserver);
-
- return uret;
- }
- static void process(bizchan_t *chan)
- {
- SOCKET conn = INVALID_SOCKET;
- struct sockaddr_in addr = {0};
- int rc;
- HANDLE evts[2] = {chan->evt, NULL};
- evts[1] = WSACreateEvent();
- // try connect to primary proxy server
- addr.sin_family = AF_INET;
- addr.sin_port = htons(chan->config.proxy_server_port);
- //addr.sin_addr.s_addr = inet_addr(chan->config.proxy_server);
- addr.sin_addr.s_addr = biz_get_inetaddr(chan, TRUE, chan->config.proxy_server);
- chan->b_primary_server = TRUE;
- conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (conn == INVALID_SOCKET) {
- goto on_error;
- }
-
- rc = prepare_socket(conn, evts[1]);
- if (rc != 0) {
- goto on_error;
- }
- rc = connect(conn, (struct sockaddr*)&addr, sizeof(addr));
- if (rc == -1 && WSAGetLastError() == WSAEWOULDBLOCK) {
- rc = 0;
- }
- if (rc == -1 && chan->config.bak_proxy_server && strlen(chan->config.bak_proxy_server)) { // try connect to back proxy server
- closesocket(conn);
- conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (conn == INVALID_SOCKET) {
- goto on_error;
- }
-
- WSAResetEvent(evts[1]);
- rc = prepare_socket(conn, evts[1]);
- if (rc != 0) {
- goto on_error;
- }
-
- addr.sin_port = htons(chan->config.bak_proxy_server_port);
- //addr.sin_addr.s_addr = inet_addr(chan->config.bak_proxy_server);
- addr.sin_addr.s_addr = biz_get_inetaddr(chan, FALSE, chan->config.bak_proxy_server);
- chan->b_primary_server = 0;
- rc = connect(conn, (struct sockaddr*)&addr, sizeof(addr));
- if (rc == -1 && WSAGetLastError() == WSAEWOULDBLOCK) {
- rc = 0;
- }
- }
- if (rc == -1) {
- goto on_error;
- }
- if (rc == 0)
- {
- proxy_ack_hdr ack_hdr;
- int ack_hdr_recv_bytes = 0;
- lpfn_cryptionfun encodefun = encodestring;
- lpfn_cryptionfun decodefun = decodestring;
- while (!chan->stop_flag && !chan->connected)
- { // wait until connected
- DWORD dwRet = WaitForMultipleObjects(2, evts, FALSE, MAX_TIMEOUT);
- if (dwRet == WAIT_OBJECT_0)
- {
- WSAResetEvent(evts[0]);
- }
- else if (dwRet == WAIT_OBJECT_0+1)
- {
- int error = 0;
- WSANETWORKEVENTS netevents;
- if (WSAEnumNetworkEvents(conn, evts[1], &netevents) != SOCKET_ERROR)
- {
- if (netevents.lNetworkEvents & FD_CONNECT)
- {
- if (netevents.iErrorCode[FD_CONNECT_BIT])
- error = netevents.iErrorCode[FD_CONNECT_BIT];
- }
- if (error == 0)
- {
- if (netevents.lNetworkEvents & FD_WRITE)
- {
- error = netevents.iErrorCode[FD_WRITE_BIT];
- if (error == 0) {
- int enc_length = KEY_LEN;
- proxy_hdr hdr = {0};
- hdr.tag[0] = 'A';
- hdr.tag[1] = 'C';
- hdr.tag[2] = 'M';
- hdr.version = ACM_PROTOCOL_VERSION;
- generate_rand_key(chan->local_pwd, KEY_LEN/2);
- //等待全部升级后再采用SM4加密
- #if ENCRYPT_CHINA
- EncWithSM4_ECB(seed_key, (unsigned char*)&chan->local_pwd[0], KEY_LEN / 2,
- (unsigned char*)&hdr.encrypt_key[0], &enc_length);
- bizlog(chan, "%s","use SM4 password_crypt_type");
- #else
- encodefun((unsigned char*)&hdr.encrypt_key[0], sizeof(hdr.encrypt_key), (unsigned char*)&chan->local_pwd[0], sizeof(chan->local_pwd));
- bizlog(chan, "use old password_crypt_type");
- #endif
- hdr.encrypt_keyhash = hash_key(chan->local_pwd, sizeof(chan->local_pwd));
- memset(hdr.callee_id, ' ', sizeof(hdr.callee_id));
- memset(hdr.caller_id, ' ', sizeof(hdr.caller_id));
- memset(hdr.client_id, ' ', sizeof(hdr.client_id));
- strncpy(&hdr.callee_id[0], chan->config.agent_id, sizeof(hdr.callee_id)-1);
- strncpy(&hdr.caller_id[0], chan->config.session_id, sizeof(hdr.caller_id)-1);
- if (chan->config.client_id) {
- strncpy(&hdr.client_id[0], chan->config.client_id, sizeof(hdr.client_id)-1);
- }
- else {
- hdr.client_id[0] = 0;
- }
- hdr.rtp_port = chan->config.video.rtp_port;
- hdr.media_desc = chan->config.video.desc;
- if (send(conn, (char*)&hdr, sizeof(hdr), 0) != sizeof(hdr)) {
- error = -1;
- }
- }
- }
- }
- if (error == 0)
- {
- if (netevents.lNetworkEvents & FD_CLOSE)
- error = -1;
- }
- if (error == 0)
- {
- if (netevents.lNetworkEvents & FD_READ)
- {
- error = netevents.iErrorCode[FD_READ_BIT];
- if (error == 0)
- {
- int t;
- do
- {
- t = recv(conn, (char*)&ack_hdr + ack_hdr_recv_bytes, sizeof(ack_hdr) - ack_hdr_recv_bytes, 0);
- if (t > 0) {
- ack_hdr_recv_bytes += t;
- if (ack_hdr_recv_bytes == sizeof(ack_hdr)) {
- int hash_result = 1;
- int dec_length = KEY_LEN;
- int dec_result = DecWithSM4_ECB(seed_key,
- (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key),
- (unsigned char*)&chan->remote_pwd[0], &dec_length);
- bizlog(chan, "use SM4 Decode password result:%d", dec_result);
- //解密成功还要做hashcheck后,才能确认password正确
- if (dec_result == 0) {
- hash_result = check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash);
- }
- if(dec_result != 0 && hash_result){
- dec_result = decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
- bizlog(chan, "use old Decode password result:%d", dec_result);
- }
- if (check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash)) {
- chan->remote_video_rtp_port = ack_hdr.rtp_port;
- chan->remote_video_desc = ack_hdr.media_desc;
- memcpy(chan->remote_client_id, ack_hdr.client_id, sizeof(chan->remote_client_id));
- chan->remote_version = ack_hdr.version;
- bizlog(chan, "remote_acm_version:%d", chan->remote_version);
- chan->connected = 1;
- break;
- }
- else {
- error = -1;
- }
- }
- }
- }
- while (t > 0 && error == 0);
- if (t <= 0 && (WSAGetLastError() != WSAEWOULDBLOCK))
- error = -1;
- }
- }
- }
- if (error != 0)
- goto on_error;
- }
- } else {
- goto on_error;
- }
- }
- }
- assert(conn != INVALID_SOCKET);
- if (chan->connected)
- {
- invoke_on_connect(chan, 0);
- chan->recv_info.offset = 0;
- rc = on_recv(chan, conn);
- if (rc)
- {
- on_close(chan);
- goto on_error;
- }
- while (!chan->stop_flag)
- {
- DWORD dwRet = WaitForMultipleObjects(2, evts, FALSE, 1000);
- if (dwRet == WAIT_OBJECT_0)
- {
- WSAResetEvent(chan->evt);
- rc = on_send(chan, conn);
- if (rc != 0)
- break;
- }
- else if (dwRet == WAIT_OBJECT_0+1)
- {
- WSANETWORKEVENTS netevents;
- if (WSAEnumNetworkEvents(conn, evts[1], &netevents) != SOCKET_ERROR)
- {
- if (netevents.lNetworkEvents & FD_READ)
- {
- rc = on_recv(chan, conn);
- }
- if (netevents.lNetworkEvents & FD_WRITE) {
- rc = on_send(chan, conn);
- }
- if (rc || (netevents.lNetworkEvents & FD_CLOSE)) {
- break;
- }
- }
- }
- else if (dwRet == WAIT_TIMEOUT)
- {
- LARGE_INTEGER now;
- GetTick(&chan->last_remote_active_time, &now);
- if (now.QuadPart - chan->last_remote_active_time.QuadPart >= PING_INTERVAL) {
- GetTick(&chan->last_local_active_time, &now);
- if (now.QuadPart - chan->last_local_active_time.QuadPart >= PING_INTERVAL) {
- bizchan_post_pkt(chan, ACM_TYPE_PING, 0, 0, 0, 0, NULL, 0);
- }
- }
- } else {
- goto on_error;
- }
- }
- on_close(chan);
- }
- on_error:
- if (!chan->connected) {
- invoke_on_connect(chan, -1); // connect failed!
- } else {
- //....
- bizlog(chan, "%s", "connected, and error!");
- }
- if (conn != INVALID_SOCKET) {
- closesocket(conn);
- }
-
- WSACloseEvent(evts[1]);
- }
- static unsigned int __stdcall work_proc(void *arg)
- {
- bizchan_t *chan = (bizchan_t *)arg;
- __try
- {
- process(chan);
- }
- __except(dump_exception(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {
- //....
- }
- return 0;
- }
- static int init_decode_func()
- {
- int ret = -1;
- if (!encodestring) {
- HMODULE hInst = LoadLibraryA("acmstrenc.dll");
- if (hInst) {
- encodestring = (lpfn_cryptionfun)GetProcAddress(hInst, "encodestring");
- }
- if (!encodestring)
- return ret;
- }
- if (!decodestring) {
- HMODULE hInst = LoadLibraryA("acmstrdec.dll");
- if (hInst) {
- decodestring = (lpfn_cryptionfun)GetProcAddress(hInst, "decodestring");
- }
- if (!decodestring)
- return ret;
- }
- if (encodestring && decodestring){
- ret = 0;
- }
- return ret;
- }
- BIZCHAN_API(int) bizchan_create(const bizchan_config_t *config, const bizchan_callback_t *cb, bizchan_t **p_chan)
- {
- bizchan_t *chan = NULL;
- if (-1 == init_decode_func()){
- return -1;
- }
- if (!config || !p_chan) {
- return -1;
- }
-
- if (config_check(config) != 0) {
- return -1;
- }
-
- if (callback_check(cb) != 0) {
- return -1;
- }
-
- chan = (bizchan_t*)malloc(sizeof(bizchan_t));
- if (!chan) {
- goto on_error;
- }
-
- memset(chan, 0, sizeof(bizchan_t));
- chan->recv_info.buf_len = DEFAULT_RX_BUF_SIZE;
- 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));
- ListEntry_InitHead(&chan->send_info.send_list);
- InitializeCriticalSection(&chan->send_info.lock);
- screen_decoder_session_create(&chan->dec_session);
- chan->evt = WSACreateEvent();
- if (!chan->evt) {
- goto on_error;
- }
-
- *p_chan = chan;
- return 0;
- on_error:
- bizchan_destroy(chan);
- return -1;
- }
- BIZCHAN_API(int) bizchan_winsync_set_cb(bizchan_t *chan, OnRecvPacket pkt_cb, OnMode mode_cb, void *user_data)
- {
- chan->winsync_on_recv_cb = pkt_cb;
- chan->mode_cb = mode_cb;
- chan->winsync_user_data = user_data;
- return 0;
- }
- BIZCHAN_API(void) bizchan_destroy(bizchan_t *chan)
- {
- if (chan) {
- if (chan->evt) {
- WSACloseEvent(chan->evt);
- chan->evt = NULL;
- }
- invoke_on_destroy(chan);
- assert(chan->work_thread == NULL);
- config_free(&chan->config);
- if (chan->recv_info.buf) {
- free(chan->recv_info.buf);
- }
-
- if (chan->recv_info.unzip_buf) {
- free(chan->recv_info.unzip_buf);
- }
- while (!ListEntry_IsEmpty(&chan->send_info.send_list)) {
- send_buf_node *p = CONTAINING_RECORD(ListEntry_RemoveListHead(&chan->send_info.send_list), send_buf_node, entry);
- free(p->buf);
- free(p);
- }
- DeleteCriticalSection(&chan->send_info.lock);
- if (chan->dec_session) {
- screen_decoder_session_destroy(chan->dec_session);
- chan->dec_session = NULL;
- }
- free(chan);
- }
- }
- BIZCHAN_API(void) bizchan_set_tag(bizchan_t *chan, void *tag)
- {
- chan->tag = tag;
- }
- BIZCHAN_API(void*) bizchan_get_tag(bizchan_t *chan)
- {
- return chan->tag;
- }
- BIZCHAN_API(int) bizchan_start_connect(bizchan_t *chan)
- {
- if (!chan) {
- return -1;
- }
-
- if (chan->work_thread) {
- return -1;
- }
-
- WSAResetEvent(chan->evt);
- chan->stop_flag = 0;
- chan->connected = 0;
- chan->work_thread = (HANDLE)_beginthreadex(NULL, 0, &work_proc, chan, 0, NULL);
- if (!chan->work_thread) {
- return -1;
- }
- // we now return, when connected, on_connect will invoked in work_proc thread
- return 0;
- }
- BIZCHAN_API(int) bizchan_start_close(bizchan_t *chan)
- {
- chan->stop_flag = 1;
- WSASetEvent(chan->evt);
- return 0;
- }
- BIZCHAN_API(int) bizchan_close(bizchan_t *chan)
- {
- if (chan->work_thread) {
- WaitForSingleObject(chan->work_thread, INFINITE);
- CloseHandle(chan->work_thread);
- chan->work_thread = NULL;
- }
- return 0;
- }
- //static FILE *tx_log_fp = NULL;
- BIZCHAN_API(int) bizchan_post_pkt(bizchan_t *chan, int type, int compress, int encrypt, int sub_type, int id, const char *pkt, int pkt_size)
- {
- send_buf_node *t;
- if (!chan->connected)
- return -1;
-
- t = (send_buf_node *)malloc(sizeof(send_buf_node));
- if (type == ACM_TYPE_SRN) {
- int cat = ACM_SRN_CAT(sub_type);
- if (cat == ACM_SRN_REQ) {
- chan->screen_img_id = id;
- }
- } else if (type == ACM_TYPE_PHT) {
- int cat = ACM_PHT_CAT(sub_type);
- if (cat == ACM_PHT_REQ) {
- chan->photo_img_id = id;
- }
- }
- if (!compress || pkt_size == 0) {
- acm_hdr *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];
- hdr->compress = 0;
- hdr->length = pkt_size;
- hdr->sub_type = sub_type;
- hdr->type = type;
- hdr->id = id;
- hdr->encrypt = !!encrypt;
- hdr->hash = hash_key(pkt, pkt_size);
- memcpy(&hdr->data[0], pkt, pkt_size);
- t->need_encrypt = encrypt;
- } else {
- qlz_state_compress state_compress;
- acm_hdr *hdr;
- int new_pkt_size;
- t->buf = (char*)malloc(2*pkt_size + sizeof(acm_hdr) + 16);
- hdr = (acm_hdr *)&t->buf[0];
- 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;
- t->left = new_pkt_size + sizeof(acm_hdr);
- } else {
- hdr->compress = 0;
- hdr->length = pkt_size;
- memcpy(&hdr->data[0], pkt, pkt_size);
- t->left = pkt_size + sizeof(acm_hdr);
- }
- hdr->type = type;
- hdr->id = id;
- hdr->sub_type = sub_type;
- hdr->encrypt = !!encrypt;
- hdr->hash = hash_key(pkt, pkt_size);
- t->sended = 0;
- t->need_encrypt = encrypt;
- }
- EnterCriticalSection(&chan->send_info.lock);
- ListEntry_AddTail(&chan->send_info.send_list, &t->entry);
- LeaveCriticalSection(&chan->send_info.lock);
- WSASetEvent(chan->evt);
- return 0;
- }
- 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, (const char*)buf, size);
- } else {
- return -1;
- }
- }
|