bizchan.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138
  1. #include "bizchan.h"
  2. #include "quicklz.h"
  3. #define WIN32_LEAN_AND_MEAN
  4. #include <Windows.h>
  5. #include <WinSock2.h>
  6. #include <WinSock.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <process.h>
  10. #include <assert.h>
  11. #include "chan_protocol.h"
  12. //#include "acmstrdec.h"
  13. //#include "acmstrenc.h"
  14. #include "openssl\rc4.h"
  15. #include "ListEntry.h"
  16. #include <screencodec.h>
  17. #include "jpeg2k.h"
  18. #include "chinaEncrypt.h"
  19. #include <DbgHelp.h>
  20. #pragma comment(lib, "dbghelp.lib")
  21. #define PING_INTERVAL 10000 // 10s
  22. #define MAX_TIMEOUT 60000 //超时时间60S,20170313修改,解决排队机闪呼的问题
  23. #define DEFAULT_RX_BUF_SIZE 8192
  24. #define KEY_LEN 16
  25. #define ENCRYPT_CHINA 1
  26. typedef struct recv_info_t {
  27. int offset;
  28. char *buf;
  29. int buf_len;
  30. char *unzip_buf;
  31. int unzip_len;
  32. qlz_state_decompress decompress_state;
  33. }recv_info_t;
  34. typedef struct send_buf_node {
  35. LIST_ENTRY entry;
  36. char *buf;
  37. int left;
  38. int sended;
  39. int need_encrypt;
  40. }send_buf_node;
  41. typedef struct send_info_t {
  42. //send_buf_node *send_list;
  43. LIST_ENTRY send_list;
  44. CRITICAL_SECTION lock;
  45. //qlz_state_compress compress_state;
  46. }send_info_t;
  47. typedef struct img_recv_t {
  48. char *data;
  49. int length;
  50. int offset;
  51. int id;
  52. }img_recv_t;
  53. struct bizchan_t
  54. {
  55. bizchan_config_t config;
  56. OnRecvPacket winsync_on_recv_cb;
  57. OnMode mode_cb;
  58. void *winsync_user_data;
  59. bizchan_callback_t cb;
  60. void *tag;
  61. HANDLE work_thread;
  62. HANDLE evt;
  63. volatile int stop_flag;
  64. recv_info_t recv_info;
  65. send_info_t send_info;
  66. int screen_img_id;
  67. int photo_img_id;
  68. int b_primary_server;
  69. int remote_video_rtp_port;
  70. int remote_video_desc;
  71. char remote_client_id[32];
  72. int connected;
  73. char local_pwd[KEY_LEN];
  74. char remote_pwd[KEY_LEN];
  75. RC4_KEY local_key;
  76. RC4_KEY remote_key;
  77. int remote_version;
  78. LARGE_INTEGER last_remote_active_time;
  79. LARGE_INTEGER last_local_active_time;
  80. screen_decoder_session_t *dec_session;
  81. };
  82. typedef int (*lpfn_cryptionfun)(unsigned char * out ,int outLen,const unsigned char * in,int inLen);
  83. static lpfn_cryptionfun decodestring = NULL;
  84. static lpfn_cryptionfun encodestring = NULL;
  85. static unsigned char seed_key []= {0x81,0x32,0x13,0xf5,0x29,0x3b,0x52,0x37,0x61,0x98,0x33,0x15,0x72,0x31,0xfe,0x34};
  86. static __inline unsigned int hash32_buf(const void *bf, size_t len, unsigned int hash)
  87. {
  88. const unsigned char *s = (const unsigned char*)bf;
  89. while (len-- != 0) /* "nemesi": k=257, r=r*257 */
  90. hash = hash * 257 + *s++;
  91. return (hash * 257);
  92. }
  93. static void generate_rand_key(char *key, int size)
  94. {
  95. int i;
  96. srand(GetTickCount()*33);
  97. for (i = 0; i < size; ++i) {
  98. key[i] = (char)(rand() & 0xff);
  99. }
  100. srand(GetCurrentProcessId() * 33);
  101. for (i = 0; i < size; ++i) {
  102. key[i] ^= (char)(rand() & 0xff);
  103. }
  104. }
  105. static __inline unsigned long hash_key(const char *key, int size)
  106. {
  107. return hash32_buf(key, size, 0);
  108. }
  109. static __inline int check_hash(char *key, int size, int hash_code)
  110. {
  111. return hash32_buf(key, size, 0) == hash_code;
  112. }
  113. static __inline void GetTick(LARGE_INTEGER *last, LARGE_INTEGER *lt)
  114. {
  115. DWORD dwNow = GetTickCount();
  116. if (last->LowPart > dwNow) {
  117. lt->LowPart = dwNow;
  118. lt->HighPart = last->HighPart + 1;
  119. } else {
  120. lt->LowPart = dwNow;
  121. lt->HighPart = last->HighPart;
  122. }
  123. }
  124. void bizlog(bizchan_t *chan, const char* fmt, ...)
  125. {
  126. if (chan){
  127. va_list arg;
  128. va_start(arg, fmt);
  129. if (chan->cb.dbg) {
  130. (*chan->cb.dbg)(chan->cb.user_data, fmt, arg);
  131. }
  132. va_end(arg);
  133. }
  134. }
  135. BIZCHAN_API(int) bizchan_lib_init()
  136. {
  137. WSADATA wsaData;
  138. return WSAStartup(0x0202, &wsaData);
  139. }
  140. BIZCHAN_API(int) bizchan_lib_term()
  141. {
  142. return WSACleanup();
  143. }
  144. static int config_copy(const bizchan_config_t *src, bizchan_config_t *dst)
  145. {
  146. memcpy(dst, src, sizeof(bizchan_config_t));
  147. dst->proxy_server = _strdup(src->proxy_server);
  148. dst->bak_proxy_server = _strdup(src->bak_proxy_server);
  149. dst->session_id = _strdup(src->session_id);
  150. dst->agent_id = _strdup(src->agent_id);
  151. dst->client_id = _strdup(src->client_id);
  152. return 0;
  153. }
  154. static int config_check(const bizchan_config_t *config)
  155. {
  156. if (!config->proxy_server)
  157. return -1;
  158. if (config->proxy_server_port <= 0 || config->proxy_server_port >= 0xffff)
  159. return -1;
  160. if (config->bak_proxy_server) {
  161. if (config->bak_proxy_server_port <= 0 || config->bak_proxy_server_port >= 0xffff)
  162. return -1;
  163. }
  164. if (!config->session_id)
  165. return -1;
  166. if (!config->agent_id)
  167. return -1;
  168. return 0;
  169. }
  170. static void config_free(bizchan_config_t *config)
  171. {
  172. free(config->proxy_server);
  173. free(config->bak_proxy_server);
  174. free(config->session_id);
  175. free(config->agent_id);
  176. free(config->client_id);
  177. }
  178. static int callback_check(const bizchan_callback_t *cb)
  179. {
  180. if (!cb->on_close) {
  181. return -1;
  182. }
  183. if (!cb->on_connect) {
  184. return -1;
  185. }
  186. if (!cb->on_recv_pkt) {
  187. return -1;
  188. }
  189. return 0;
  190. }
  191. static void invoke_on_connect(bizchan_t *chan, int error)
  192. {
  193. if (error == 0) {
  194. chan->cb.on_connect(chan,
  195. error,
  196. chan->b_primary_server ? chan->config.proxy_server : chan->config.bak_proxy_server,
  197. chan->remote_video_rtp_port,
  198. chan->remote_video_desc,
  199. chan->remote_client_id,
  200. chan->cb.user_data);
  201. }
  202. else {
  203. chan->cb.on_connect(chan,
  204. error,
  205. NULL,
  206. 0,
  207. 0,
  208. NULL,
  209. chan->cb.user_data);
  210. }
  211. }
  212. //static FILE *rx_log_fp = NULL;
  213. static void invoke_on_recv_pkt(bizchan_t *chan, int type, int sub_type, int id, const char *pkt, int pkt_size)
  214. {
  215. /*if (rx_log_fp == NULL) {
  216. rx_log_fp = fopen("c:\\rxlog.txt", "wt");
  217. fprintf(rx_log_fp, "===================\n");
  218. }
  219. {
  220. SYSTEMTIME st;
  221. GetLocalTime(&st);
  222. fprintf(rx_log_fp, "[%02d:%02d:%02d.%03d] type = %d, sub_type = %d, id = %d, pkt_size = %d, hash = %d\n",
  223. st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
  224. type, sub_type, id, pkt_size, hash32_buf(pkt, pkt_size, 0));
  225. fflush(rx_log_fp);
  226. }*/
  227. //Dbg(chan, "invoke_on_recv_pkt, type:%d, sub_type:%d, id:%d, pkt_size:%d", type, sub_type, id, pkt_size);
  228. if (type == ACM_TYPE_SRN) {
  229. int cat = ACM_SRN_CAT(sub_type);
  230. if (cat == ACM_SRN_ANS) {
  231. if (id == chan->screen_img_id) {
  232. if (pkt_size == 4)
  233. {
  234. int err;
  235. memcpy(&err, pkt, 4);
  236. chan->cb.on_recv_screen(chan, id, err, 0, 0, NULL, 0, chan->cb.user_data);
  237. }
  238. else
  239. {
  240. int size = 0;
  241. int width, height;
  242. int rc;
  243. char *dec_buf = NULL;
  244. rc = screen_decoder_session_decode(chan->dec_session, pkt, pkt_size, &width, &height, dec_buf, &size);
  245. if (rc == 0) {
  246. dec_buf = (char*)malloc(size);
  247. rc = screen_decoder_session_decode(chan->dec_session, pkt, pkt_size, &width, &height, dec_buf, &size);
  248. }
  249. if (rc == 0) {
  250. chan->cb.on_recv_screen(chan, id, 0, width, height, dec_buf, size, chan->cb.user_data);
  251. } else {
  252. chan->cb.on_recv_screen(chan, id, rc, 0, 0, NULL, 0, chan->cb.user_data);
  253. }
  254. if (dec_buf)
  255. free(dec_buf);
  256. }
  257. }
  258. } else
  259. {
  260. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  261. }
  262. } else if (type == ACM_TYPE_PHT) {
  263. int cat = ACM_PHT_CAT(sub_type);
  264. if (cat == ACM_PHT_ANS)
  265. {
  266. if (id == chan->photo_img_id) {
  267. if (pkt_size == 4) {
  268. int err;
  269. memcpy(&err, pkt, 4);
  270. chan->cb.on_recv_photo(chan, id, err, 0, 0, NULL, 0, chan->cb.user_data);
  271. } else {
  272. jpeg2k_raw_image raw_image = {0};
  273. jpeg2k_coded_image codec_image = {0};
  274. int rc;
  275. codec_image.data = (unsigned char*)pkt;
  276. codec_image.len = pkt_size;
  277. rc = jpeg2k_decode(&raw_image, &codec_image);
  278. if (rc == 0) {
  279. 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);
  280. jpeg2k_decode_free(&raw_image);
  281. } else {
  282. chan->cb.on_recv_photo(chan, id, rc, 0, 0, NULL, 0, chan->cb.user_data);
  283. }
  284. }
  285. }
  286. } else {
  287. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  288. }
  289. } else if (type == ACM_TYPE_SYNC) {
  290. if (chan->winsync_on_recv_cb) {
  291. chan->winsync_on_recv_cb(sub_type, pkt, pkt_size, chan->winsync_user_data);
  292. }
  293. //同时上报应用层,用于应用层判断采用哪种同步方式(Sivilight或者chrome H5)
  294. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  295. } else if (type == ACM_TYPE_MODE) {
  296. if (chan->mode_cb) {
  297. chan->mode_cb(TRUE, chan->winsync_user_data);
  298. }
  299. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  300. } else if (type == ACM_TYPE_PING) {
  301. //..... remote ping, nothing todo
  302. } else {
  303. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  304. }
  305. }
  306. static void invoke_on_close(bizchan_t *chan)
  307. {
  308. if (chan->cb.on_close) {
  309. chan->cb.on_close(chan, chan->cb.user_data);
  310. }
  311. }
  312. static void invoke_on_destroy(bizchan_t *chan)
  313. {
  314. if (chan->cb.on_destroy) {
  315. chan->cb.on_destroy(chan, chan->cb.user_data);
  316. }
  317. }
  318. static FILE *fp = NULL;
  319. static int on_recv2(bizchan_t *chan, SOCKET conn)
  320. {
  321. int n;
  322. char buf[0x10000+sizeof(acm_hdr)];
  323. if (fp == NULL) {
  324. fp = fopen ("g:\\rx.dat", "wb");
  325. }
  326. do {
  327. n = recv(conn, buf, sizeof(buf), 0);
  328. if (n > 0) {
  329. fwrite(buf, 1, n, fp);
  330. fflush(fp);
  331. }
  332. } while (n > 0);
  333. return (n == 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
  334. }
  335. static int on_recv(bizchan_t *chan, SOCKET conn)
  336. {
  337. recv_info_t *ri = &chan->recv_info;
  338. int n;
  339. do {
  340. n = recv(conn, ri->buf+ri->offset, ri->buf_len-ri->offset, 0);
  341. if (n > 0) {
  342. int i = 0;
  343. ri->offset += n;
  344. GetTick(&chan->last_remote_active_time, &chan->last_remote_active_time);
  345. while (ri->offset-i >= sizeof(acm_hdr)) {
  346. acm_hdr *hdr = (acm_hdr*)&ri->buf[i];
  347. //Dbg(chan, "on_recv, i:%d offset:%d, recv_length:%d", i, ri->offset, n);
  348. //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);
  349. if (hdr->length == 0) {
  350. printf("broken");
  351. }
  352. if (ri->offset-i >= hdr->length+sizeof(acm_hdr)) {
  353. if (hdr->encrypt)
  354. {
  355. int dec_length = hdr->length;
  356. char *dec_buf = (char*)malloc(hdr->length);
  357. 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);
  358. if (sm4_dec_result != 0){
  359. bizlog(chan, "DecStrWithSM4_ECB failed, type:%u, sub_type:%u, length:%lu", hdr->type, hdr->sub_type, hdr->length);
  360. RC4_set_key(&chan->remote_key, sizeof(chan->remote_pwd), (unsigned char*)chan->remote_pwd);
  361. RC4(&chan->remote_key, hdr->length, (const unsigned char*)(&hdr->data[0]), (unsigned char*)dec_buf);
  362. dec_length = hdr->length;
  363. }
  364. if (hdr->compress)
  365. {
  366. int len = (int)qlz_size_decompressed(dec_buf);
  367. char *unzip_buf = (char*)malloc(len);
  368. len = qlz_decompress(dec_buf, unzip_buf, &ri->decompress_state);
  369. if (check_hash(unzip_buf, len, hdr->hash))
  370. {
  371. invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
  372. } else {
  373. //OutputDebugStringA("pkt hash failed!\n");
  374. 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);
  375. }
  376. free(unzip_buf);
  377. } else {
  378. //sm4解密后hdr->length长度与内容长度不一致,采用dec_length变量
  379. if (check_hash(dec_buf, dec_length, hdr->hash)) {
  380. invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, dec_buf, dec_length);
  381. }
  382. else {
  383. //OutputDebugStringA("pkt hash failed!\n");
  384. 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);
  385. }
  386. }
  387. free(dec_buf);
  388. }
  389. else
  390. {
  391. if (hdr->compress)
  392. {
  393. int len = (int)qlz_size_decompressed((const char*)&hdr->data[0]);
  394. char *unzip_buf = (char*)malloc(len);
  395. len = qlz_decompress((const char*)&hdr->data[0], unzip_buf, &ri->decompress_state);
  396. if (check_hash(unzip_buf, len, hdr->hash)) {
  397. invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
  398. } else {
  399. //OutputDebugStringA("pkt hash failed!\n");
  400. 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);
  401. }
  402. free(unzip_buf);
  403. }
  404. else
  405. {
  406. if (check_hash((char*)&hdr->data[0], hdr->length, hdr->hash))
  407. {
  408. invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, (const char*)&hdr->data[0], hdr->length);
  409. } else {
  410. //OutputDebugStringA("pkt hash failed!\n");
  411. bizlog(chan, "uncompress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu", hdr->type, hdr->sub_type, hdr->length, hdr->hash);
  412. }
  413. }
  414. }
  415. i += hdr->length+sizeof(acm_hdr);
  416. } else {
  417. break;
  418. }
  419. }
  420. if (i != ri->offset) {
  421. memmove(&ri->buf[0], &ri->buf[i], ri->offset-i);
  422. }
  423. ri->offset -= i;
  424. if (ri->offset == ri->buf_len) { // double large
  425. ri->buf_len = 2 * ri->buf_len;
  426. ri->buf = (char*)realloc(ri->buf, ri->buf_len);
  427. }
  428. }
  429. } while (n > 0);
  430. return (n == 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
  431. }
  432. static int on_send(bizchan_t *chan, SOCKET conn)
  433. {
  434. send_info_t *si = &chan->send_info;
  435. int n = 0;
  436. EnterCriticalSection(&si->lock);
  437. if (!ListEntry_IsEmpty(&si->send_list)) {
  438. do {
  439. send_buf_node *t = CONTAINING_RECORD(ListEntry_GetHead(&si->send_list), send_buf_node, entry);
  440. if (t->need_encrypt) {
  441. //SM4加密,密文会比明文长16字节
  442. int enc_length = t->left + sizeof(acm_hdr)+16;
  443. acm_hdr *hdr = (acm_hdr*)t->buf;
  444. char *enc_buf = (char*)malloc(t->left+sizeof(acm_hdr) + 16);
  445. //version为2代表支持国密,采用SM4加密
  446. if(chan->remote_version != 1){
  447. 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);
  448. hdr->length = enc_length;
  449. t->left = enc_length + sizeof(acm_hdr);
  450. //Dbg(chan, "enc_length:%d", enc_length);
  451. }
  452. else {
  453. RC4_set_key(&chan->local_key, sizeof(chan->local_pwd), (unsigned char*)chan->local_pwd);
  454. RC4(&chan->local_key, t->left, (const unsigned char*)(&hdr->data[0]), (unsigned char*)(enc_buf+sizeof(acm_hdr)));
  455. }
  456. memcpy(enc_buf, hdr, sizeof(acm_hdr));
  457. free(t->buf);
  458. t->buf = enc_buf;
  459. t->need_encrypt = 0;
  460. }
  461. n = send(conn, t->buf+t->sended, t->left, 0);
  462. if (n > 0) {
  463. char tmp[32] = {0};
  464. _snprintf(tmp, 32, "send out %d bytes!\n", n);
  465. OutputDebugStringA(tmp);
  466. //Dbg(chan, tmp);
  467. t->left -= n;
  468. t->sended += n;
  469. if (t->left == 0) {
  470. ListEntry_DeleteNode(&t->entry);
  471. free(t->buf);
  472. free(t);
  473. }
  474. GetTick(&chan->last_local_active_time, &chan->last_local_active_time);
  475. }
  476. } while (n > 0 && !ListEntry_IsEmpty(&si->send_list));
  477. }
  478. LeaveCriticalSection(&si->lock);
  479. return (n >= 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
  480. }
  481. static void on_close(bizchan_t *chan)
  482. {
  483. invoke_on_close(chan);
  484. }
  485. static int prepare_socket(SOCKET s, HANDLE evt)
  486. {
  487. BOOL opt = TRUE;
  488. int rc;
  489. rc = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
  490. opt = TRUE;
  491. if (rc == 0)
  492. rc = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, (char*)&opt, sizeof(opt));
  493. if (rc == 0)
  494. rc = WSAEventSelect(s, evt, FD_CONNECT | FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE);
  495. return rc;
  496. }
  497. static void dump_exception(PEXCEPTION_POINTERS ExceptionInfo)
  498. {
  499. char tmp[MAX_PATH];
  500. HANDLE hDumpFile;
  501. sprintf(tmp, ".\\bizchan_%d.dmp", GetCurrentProcessId());
  502. hDumpFile = CreateFileA( tmp, GENERIC_READ | GENERIC_WRITE,
  503. 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  504. if( ( hDumpFile != NULL ) && ( hDumpFile != INVALID_HANDLE_VALUE ) )
  505. {
  506. MINIDUMP_EXCEPTION_INFORMATION mdei;
  507. MINIDUMP_TYPE mdt;
  508. mdei.ThreadId = GetCurrentThreadId();
  509. mdei.ExceptionPointers = ExceptionInfo;
  510. mdei.ClientPointers = FALSE;
  511. mdt = MiniDumpWithFullMemory;
  512. MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
  513. hDumpFile, mdt, (ExceptionInfo != 0) ? &mdei : 0, 0, 0 );
  514. CloseHandle( hDumpFile );
  515. }
  516. }
  517. static BOOL addr_is_domain(const char* pserver_addr)
  518. {
  519. BOOL bret = FALSE;
  520. if (NULL == pserver_addr){
  521. return bret;
  522. }
  523. if (strstr(pserver_addr, ".com") ||strstr(pserver_addr, ".cn")){
  524. bret = TRUE;
  525. }
  526. return bret;
  527. }
  528. static unsigned long biz_get_inetaddr(bizchan_t *chan, BOOL bprimary, const char* pserver)
  529. {
  530. unsigned long uret = 0;
  531. if (NULL == pserver){
  532. return uret;
  533. }
  534. uret = inet_addr(pserver);
  535. return uret;
  536. }
  537. static void process(bizchan_t *chan)
  538. {
  539. SOCKET conn = INVALID_SOCKET;
  540. struct sockaddr_in addr = {0};
  541. int rc;
  542. HANDLE evts[2] = {chan->evt, NULL};
  543. evts[1] = WSACreateEvent();
  544. // try connect to primary proxy server
  545. addr.sin_family = AF_INET;
  546. addr.sin_port = htons(chan->config.proxy_server_port);
  547. //addr.sin_addr.s_addr = inet_addr(chan->config.proxy_server);
  548. addr.sin_addr.s_addr = biz_get_inetaddr(chan, TRUE, chan->config.proxy_server);
  549. chan->b_primary_server = TRUE;
  550. conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  551. if (conn == INVALID_SOCKET) {
  552. goto on_error;
  553. }
  554. rc = prepare_socket(conn, evts[1]);
  555. if (rc != 0) {
  556. goto on_error;
  557. }
  558. rc = connect(conn, (struct sockaddr*)&addr, sizeof(addr));
  559. if (rc == -1 && WSAGetLastError() == WSAEWOULDBLOCK) {
  560. rc = 0;
  561. }
  562. if (rc == -1 && chan->config.bak_proxy_server && strlen(chan->config.bak_proxy_server)) { // try connect to back proxy server
  563. closesocket(conn);
  564. conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  565. if (conn == INVALID_SOCKET) {
  566. goto on_error;
  567. }
  568. WSAResetEvent(evts[1]);
  569. rc = prepare_socket(conn, evts[1]);
  570. if (rc != 0) {
  571. goto on_error;
  572. }
  573. addr.sin_port = htons(chan->config.bak_proxy_server_port);
  574. //addr.sin_addr.s_addr = inet_addr(chan->config.bak_proxy_server);
  575. addr.sin_addr.s_addr = biz_get_inetaddr(chan, FALSE, chan->config.bak_proxy_server);
  576. chan->b_primary_server = 0;
  577. rc = connect(conn, (struct sockaddr*)&addr, sizeof(addr));
  578. if (rc == -1 && WSAGetLastError() == WSAEWOULDBLOCK) {
  579. rc = 0;
  580. }
  581. }
  582. if (rc == -1) {
  583. goto on_error;
  584. }
  585. if (rc == 0)
  586. {
  587. proxy_ack_hdr ack_hdr;
  588. int ack_hdr_recv_bytes = 0;
  589. lpfn_cryptionfun encodefun = encodestring;
  590. lpfn_cryptionfun decodefun = decodestring;
  591. while (!chan->stop_flag && !chan->connected)
  592. { // wait until connected
  593. DWORD dwRet = WaitForMultipleObjects(2, evts, FALSE, MAX_TIMEOUT);
  594. if (dwRet == WAIT_OBJECT_0)
  595. {
  596. WSAResetEvent(evts[0]);
  597. }
  598. else if (dwRet == WAIT_OBJECT_0+1)
  599. {
  600. int error = 0;
  601. WSANETWORKEVENTS netevents;
  602. if (WSAEnumNetworkEvents(conn, evts[1], &netevents) != SOCKET_ERROR)
  603. {
  604. if (netevents.lNetworkEvents & FD_CONNECT)
  605. {
  606. if (netevents.iErrorCode[FD_CONNECT_BIT])
  607. error = netevents.iErrorCode[FD_CONNECT_BIT];
  608. }
  609. if (error == 0)
  610. {
  611. if (netevents.lNetworkEvents & FD_WRITE)
  612. {
  613. error = netevents.iErrorCode[FD_WRITE_BIT];
  614. if (error == 0) {
  615. int enc_length = KEY_LEN;
  616. proxy_hdr hdr = {0};
  617. hdr.tag[0] = 'A';
  618. hdr.tag[1] = 'C';
  619. hdr.tag[2] = 'M';
  620. hdr.version = ACM_PROTOCOL_VERSION;
  621. generate_rand_key(chan->local_pwd, KEY_LEN/2);
  622. //等待全部升级后再采用SM4加密
  623. #if ENCRYPT_CHINA
  624. EncWithSM4_ECB(seed_key, (unsigned char*)&chan->local_pwd[0], KEY_LEN / 2,
  625. (unsigned char*)&hdr.encrypt_key[0], &enc_length);
  626. bizlog(chan, "%s","use SM4 password_crypt_type");
  627. #else
  628. encodefun((unsigned char*)&hdr.encrypt_key[0], sizeof(hdr.encrypt_key), (unsigned char*)&chan->local_pwd[0], sizeof(chan->local_pwd));
  629. bizlog(chan, "use old password_crypt_type");
  630. #endif
  631. hdr.encrypt_keyhash = hash_key(chan->local_pwd, sizeof(chan->local_pwd));
  632. memset(hdr.callee_id, ' ', sizeof(hdr.callee_id));
  633. memset(hdr.caller_id, ' ', sizeof(hdr.caller_id));
  634. memset(hdr.client_id, ' ', sizeof(hdr.client_id));
  635. strncpy(&hdr.callee_id[0], chan->config.agent_id, sizeof(hdr.callee_id)-1);
  636. strncpy(&hdr.caller_id[0], chan->config.session_id, sizeof(hdr.caller_id)-1);
  637. if (chan->config.client_id) {
  638. strncpy(&hdr.client_id[0], chan->config.client_id, sizeof(hdr.client_id)-1);
  639. }
  640. else {
  641. hdr.client_id[0] = 0;
  642. }
  643. hdr.rtp_port = chan->config.video.rtp_port;
  644. hdr.media_desc = chan->config.video.desc;
  645. if (send(conn, (char*)&hdr, sizeof(hdr), 0) != sizeof(hdr)) {
  646. error = -1;
  647. }
  648. }
  649. }
  650. }
  651. if (error == 0)
  652. {
  653. if (netevents.lNetworkEvents & FD_CLOSE)
  654. error = -1;
  655. }
  656. if (error == 0)
  657. {
  658. if (netevents.lNetworkEvents & FD_READ)
  659. {
  660. error = netevents.iErrorCode[FD_READ_BIT];
  661. if (error == 0)
  662. {
  663. int t;
  664. do
  665. {
  666. t = recv(conn, (char*)&ack_hdr + ack_hdr_recv_bytes, sizeof(ack_hdr) - ack_hdr_recv_bytes, 0);
  667. if (t > 0) {
  668. ack_hdr_recv_bytes += t;
  669. if (ack_hdr_recv_bytes == sizeof(ack_hdr)) {
  670. int hash_result = 1;
  671. int dec_length = KEY_LEN;
  672. int dec_result = DecWithSM4_ECB(seed_key,
  673. (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key),
  674. (unsigned char*)&chan->remote_pwd[0], &dec_length);
  675. bizlog(chan, "use SM4 Decode password result:%d", dec_result);
  676. //解密成功还要做hashcheck后,才能确认password正确
  677. if (dec_result == 0) {
  678. hash_result = check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash);
  679. }
  680. if(dec_result != 0 && hash_result){
  681. 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));
  682. bizlog(chan, "use old Decode password result:%d", dec_result);
  683. }
  684. if (check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash)) {
  685. chan->remote_video_rtp_port = ack_hdr.rtp_port;
  686. chan->remote_video_desc = ack_hdr.media_desc;
  687. memcpy(chan->remote_client_id, ack_hdr.client_id, sizeof(chan->remote_client_id));
  688. chan->remote_version = ack_hdr.version;
  689. bizlog(chan, "remote_acm_version:%d", chan->remote_version);
  690. chan->connected = 1;
  691. break;
  692. }
  693. else {
  694. error = -1;
  695. }
  696. }
  697. }
  698. }
  699. while (t > 0 && error == 0);
  700. if (t <= 0 && (WSAGetLastError() != WSAEWOULDBLOCK))
  701. error = -1;
  702. }
  703. }
  704. }
  705. if (error != 0)
  706. goto on_error;
  707. }
  708. } else {
  709. goto on_error;
  710. }
  711. }
  712. }
  713. assert(conn != INVALID_SOCKET);
  714. if (chan->connected)
  715. {
  716. invoke_on_connect(chan, 0);
  717. chan->recv_info.offset = 0;
  718. rc = on_recv(chan, conn);
  719. if (rc)
  720. {
  721. on_close(chan);
  722. goto on_error;
  723. }
  724. while (!chan->stop_flag)
  725. {
  726. DWORD dwRet = WaitForMultipleObjects(2, evts, FALSE, 1000);
  727. if (dwRet == WAIT_OBJECT_0)
  728. {
  729. WSAResetEvent(chan->evt);
  730. rc = on_send(chan, conn);
  731. if (rc != 0)
  732. break;
  733. }
  734. else if (dwRet == WAIT_OBJECT_0+1)
  735. {
  736. WSANETWORKEVENTS netevents;
  737. if (WSAEnumNetworkEvents(conn, evts[1], &netevents) != SOCKET_ERROR)
  738. {
  739. if (netevents.lNetworkEvents & FD_READ)
  740. {
  741. rc = on_recv(chan, conn);
  742. }
  743. if (netevents.lNetworkEvents & FD_WRITE) {
  744. rc = on_send(chan, conn);
  745. }
  746. if (rc || (netevents.lNetworkEvents & FD_CLOSE)) {
  747. break;
  748. }
  749. }
  750. }
  751. else if (dwRet == WAIT_TIMEOUT)
  752. {
  753. LARGE_INTEGER now;
  754. GetTick(&chan->last_remote_active_time, &now);
  755. if (now.QuadPart - chan->last_remote_active_time.QuadPart >= PING_INTERVAL) {
  756. GetTick(&chan->last_local_active_time, &now);
  757. if (now.QuadPart - chan->last_local_active_time.QuadPart >= PING_INTERVAL) {
  758. bizchan_post_pkt(chan, ACM_TYPE_PING, 0, 0, 0, 0, NULL, 0);
  759. }
  760. }
  761. } else {
  762. goto on_error;
  763. }
  764. }
  765. on_close(chan);
  766. }
  767. on_error:
  768. if (!chan->connected) {
  769. invoke_on_connect(chan, -1); // connect failed!
  770. } else {
  771. //....
  772. bizlog(chan, "%s", "connected, and error!");
  773. }
  774. if (conn != INVALID_SOCKET) {
  775. closesocket(conn);
  776. }
  777. WSACloseEvent(evts[1]);
  778. }
  779. static unsigned int __stdcall work_proc(void *arg)
  780. {
  781. bizchan_t *chan = (bizchan_t *)arg;
  782. __try
  783. {
  784. process(chan);
  785. }
  786. __except(dump_exception(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {
  787. //....
  788. }
  789. return 0;
  790. }
  791. static int init_decode_func()
  792. {
  793. int ret = -1;
  794. if (!encodestring) {
  795. HMODULE hInst = LoadLibraryA("acmstrenc.dll");
  796. if (hInst) {
  797. encodestring = (lpfn_cryptionfun)GetProcAddress(hInst, "encodestring");
  798. }
  799. if (!encodestring)
  800. return ret;
  801. }
  802. if (!decodestring) {
  803. HMODULE hInst = LoadLibraryA("acmstrdec.dll");
  804. if (hInst) {
  805. decodestring = (lpfn_cryptionfun)GetProcAddress(hInst, "decodestring");
  806. }
  807. if (!decodestring)
  808. return ret;
  809. }
  810. if (encodestring && decodestring){
  811. ret = 0;
  812. }
  813. return ret;
  814. }
  815. BIZCHAN_API(int) bizchan_create(const bizchan_config_t *config, const bizchan_callback_t *cb, bizchan_t **p_chan)
  816. {
  817. bizchan_t *chan = NULL;
  818. if (-1 == init_decode_func()){
  819. return -1;
  820. }
  821. if (!config || !p_chan) {
  822. return -1;
  823. }
  824. if (config_check(config) != 0) {
  825. return -1;
  826. }
  827. if (callback_check(cb) != 0) {
  828. return -1;
  829. }
  830. chan = (bizchan_t*)malloc(sizeof(bizchan_t));
  831. if (!chan) {
  832. goto on_error;
  833. }
  834. memset(chan, 0, sizeof(bizchan_t));
  835. chan->recv_info.buf_len = DEFAULT_RX_BUF_SIZE;
  836. chan->recv_info.buf = (char*)malloc(chan->recv_info.buf_len);
  837. if (!chan->recv_info.buf) {
  838. goto on_error;
  839. }
  840. if (config_copy(config, &chan->config) != 0) {
  841. goto on_error;
  842. }
  843. memcpy(&chan->cb, cb, sizeof(bizchan_callback_t));
  844. ListEntry_InitHead(&chan->send_info.send_list);
  845. InitializeCriticalSection(&chan->send_info.lock);
  846. screen_decoder_session_create(&chan->dec_session);
  847. chan->evt = WSACreateEvent();
  848. if (!chan->evt) {
  849. goto on_error;
  850. }
  851. *p_chan = chan;
  852. return 0;
  853. on_error:
  854. bizchan_destroy(chan);
  855. return -1;
  856. }
  857. BIZCHAN_API(int) bizchan_winsync_set_cb(bizchan_t *chan, OnRecvPacket pkt_cb, OnMode mode_cb, void *user_data)
  858. {
  859. chan->winsync_on_recv_cb = pkt_cb;
  860. chan->mode_cb = mode_cb;
  861. chan->winsync_user_data = user_data;
  862. return 0;
  863. }
  864. BIZCHAN_API(void) bizchan_destroy(bizchan_t *chan)
  865. {
  866. if (chan) {
  867. if (chan->evt) {
  868. WSACloseEvent(chan->evt);
  869. chan->evt = NULL;
  870. }
  871. invoke_on_destroy(chan);
  872. assert(chan->work_thread == NULL);
  873. config_free(&chan->config);
  874. if (chan->recv_info.buf) {
  875. free(chan->recv_info.buf);
  876. }
  877. if (chan->recv_info.unzip_buf) {
  878. free(chan->recv_info.unzip_buf);
  879. }
  880. while (!ListEntry_IsEmpty(&chan->send_info.send_list)) {
  881. send_buf_node *p = CONTAINING_RECORD(ListEntry_RemoveListHead(&chan->send_info.send_list), send_buf_node, entry);
  882. free(p->buf);
  883. free(p);
  884. }
  885. DeleteCriticalSection(&chan->send_info.lock);
  886. if (chan->dec_session) {
  887. screen_decoder_session_destroy(chan->dec_session);
  888. chan->dec_session = NULL;
  889. }
  890. free(chan);
  891. }
  892. }
  893. BIZCHAN_API(void) bizchan_set_tag(bizchan_t *chan, void *tag)
  894. {
  895. chan->tag = tag;
  896. }
  897. BIZCHAN_API(void*) bizchan_get_tag(bizchan_t *chan)
  898. {
  899. return chan->tag;
  900. }
  901. BIZCHAN_API(int) bizchan_start_connect(bizchan_t *chan)
  902. {
  903. if (!chan) {
  904. return -1;
  905. }
  906. if (chan->work_thread) {
  907. return -1;
  908. }
  909. WSAResetEvent(chan->evt);
  910. chan->stop_flag = 0;
  911. chan->connected = 0;
  912. chan->work_thread = (HANDLE)_beginthreadex(NULL, 0, &work_proc, chan, 0, NULL);
  913. if (!chan->work_thread) {
  914. return -1;
  915. }
  916. // we now return, when connected, on_connect will invoked in work_proc thread
  917. return 0;
  918. }
  919. BIZCHAN_API(int) bizchan_start_close(bizchan_t *chan)
  920. {
  921. chan->stop_flag = 1;
  922. WSASetEvent(chan->evt);
  923. return 0;
  924. }
  925. BIZCHAN_API(int) bizchan_close(bizchan_t *chan)
  926. {
  927. if (chan->work_thread) {
  928. WaitForSingleObject(chan->work_thread, INFINITE);
  929. CloseHandle(chan->work_thread);
  930. chan->work_thread = NULL;
  931. }
  932. return 0;
  933. }
  934. //static FILE *tx_log_fp = NULL;
  935. 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)
  936. {
  937. send_buf_node *t;
  938. if (!chan->connected)
  939. return -1;
  940. t = (send_buf_node *)malloc(sizeof(send_buf_node));
  941. if (type == ACM_TYPE_SRN) {
  942. int cat = ACM_SRN_CAT(sub_type);
  943. if (cat == ACM_SRN_REQ) {
  944. chan->screen_img_id = id;
  945. }
  946. } else if (type == ACM_TYPE_PHT) {
  947. int cat = ACM_PHT_CAT(sub_type);
  948. if (cat == ACM_PHT_REQ) {
  949. chan->photo_img_id = id;
  950. }
  951. }
  952. if (!compress || pkt_size == 0) {
  953. acm_hdr *hdr;
  954. t->buf = (char*)malloc(pkt_size + sizeof(acm_hdr));
  955. t->left = pkt_size + sizeof(acm_hdr);
  956. t->sended = 0;
  957. hdr = (acm_hdr*)&t->buf[0];
  958. hdr->compress = 0;
  959. hdr->length = pkt_size;
  960. hdr->sub_type = sub_type;
  961. hdr->type = type;
  962. hdr->id = id;
  963. hdr->encrypt = !!encrypt;
  964. hdr->hash = hash_key(pkt, pkt_size);
  965. memcpy(&hdr->data[0], pkt, pkt_size);
  966. t->need_encrypt = encrypt;
  967. } else {
  968. qlz_state_compress state_compress;
  969. acm_hdr *hdr;
  970. int new_pkt_size;
  971. t->buf = (char*)malloc(2*pkt_size + sizeof(acm_hdr) + 16);
  972. hdr = (acm_hdr *)&t->buf[0];
  973. new_pkt_size = (int)qlz_compress(pkt, (char*)&hdr->data[0], pkt_size, &state_compress);
  974. if (new_pkt_size < pkt_size) {
  975. hdr->compress = 1;
  976. hdr->length = new_pkt_size;
  977. t->left = new_pkt_size + sizeof(acm_hdr);
  978. } else {
  979. hdr->compress = 0;
  980. hdr->length = pkt_size;
  981. memcpy(&hdr->data[0], pkt, pkt_size);
  982. t->left = pkt_size + sizeof(acm_hdr);
  983. }
  984. hdr->type = type;
  985. hdr->id = id;
  986. hdr->sub_type = sub_type;
  987. hdr->encrypt = !!encrypt;
  988. hdr->hash = hash_key(pkt, pkt_size);
  989. t->sended = 0;
  990. t->need_encrypt = encrypt;
  991. }
  992. EnterCriticalSection(&chan->send_info.lock);
  993. ListEntry_AddTail(&chan->send_info.send_list, &t->entry);
  994. LeaveCriticalSection(&chan->send_info.lock);
  995. WSASetEvent(chan->evt);
  996. return 0;
  997. }
  998. BIZCHAN_API(int) bizchan_winsync_send(bizchan_t *chan, int sub_type, const void *buf, int size)
  999. {
  1000. if (chan && chan->work_thread) {
  1001. return bizchan_post_pkt(chan, ACM_TYPE_SYNC, 1, sub_type, 1, 0, (const char*)buf, size);
  1002. } else {
  1003. return -1;
  1004. }
  1005. }