bizchan.cpp 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691
  1. #include "bizchan.h"
  2. #include "quicklz.h"
  3. #ifdef RVC_OS_WIN
  4. #define WIN32_LEAN_AND_MEAN
  5. #include <Windows.h>
  6. #include <WinSock2.h>
  7. #include <WinSock.h>
  8. #include <process.h>
  9. #else
  10. #include <sys/socket.h>
  11. #include <fcntl.h>
  12. #include <errno.h>
  13. #include <unistd.h>
  14. #include <pthread.h>
  15. #include <netinet/in.h>
  16. #include <string.h>
  17. #include <arpa/inet.h>
  18. #endif
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <assert.h>
  22. #include "chan_protocol.h"
  23. //#include "acmstrdec.h"
  24. //#include "acmstrenc.h"
  25. #include "openssl/rc4.h"
  26. #include "ListEntry.h"
  27. #include "screencodec.h"
  28. #include "jpeg2k.h"
  29. #include "chinaEncrypt.h"
  30. #ifdef RVC_OS_WIN
  31. #include <DbgHelp.h>
  32. #pragma comment(lib, "dbghelp.lib")
  33. #endif
  34. #define PING_INTERVAL 10000 // 10s
  35. #define MAX_TIMEOUT 60000 //超时时间60S,20170313修改,解决排队机闪呼的问题
  36. #define DEFAULT_RX_BUF_SIZE 8192
  37. #define KEY_LEN 16
  38. #define ENCRYPT_CHINA 1
  39. #ifndef RVC_OS_WIN
  40. #include "SpBase.h"
  41. typedef int SOCKET;
  42. #ifndef INVALID_SOCKET
  43. #define INVALID_SOCKET (SOCKET)(~0)
  44. #endif
  45. #ifndef SOCKET_ERROR
  46. #define SOCKET_ERROR (-1)
  47. #endif
  48. #define max(a,b) (((a) > (b)) ? (a) : (b))
  49. #define min(a,b) (((a) < (b)) ? (a) : (b))
  50. unsigned long GetTickCount()
  51. {
  52. struct timespec ts;
  53. clock_gettime(CLOCK_MONOTONIC, &ts);
  54. return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
  55. }
  56. #endif
  57. typedef struct recv_info_t {
  58. int offset;
  59. char *buf;
  60. int buf_len;
  61. char *unzip_buf;
  62. int unzip_len;
  63. qlz_state_decompress decompress_state;
  64. }recv_info_t;
  65. typedef struct send_buf_node {
  66. LIST_ENTRY entry;
  67. char *buf;
  68. int left;
  69. int sended;
  70. int need_encrypt;
  71. }send_buf_node;
  72. typedef struct send_info_t {
  73. //send_buf_node *send_list;
  74. LIST_ENTRY send_list;
  75. #ifdef RVC_OS_WIN
  76. CRITICAL_SECTION lock;
  77. #else
  78. pthread_mutexattr_t attr;
  79. pthread_mutex_t lock;
  80. #endif
  81. //qlz_state_compress compress_state;
  82. }send_info_t;
  83. typedef struct img_recv_t {
  84. char *data;
  85. int length;
  86. int offset;
  87. int id;
  88. }img_recv_t;
  89. struct bizchan_t
  90. {
  91. bizchan_config_t config;
  92. OnRecvPacket winsync_on_recv_cb;
  93. OnMode mode_cb;
  94. void *winsync_user_data;
  95. bizchan_callback_t cb;
  96. void *tag;
  97. #ifdef RVC_OS_WIN
  98. HANDLE work_thread;
  99. HANDLE evt;
  100. #else
  101. pthread_t work_thread;
  102. int evt[2];//pipe
  103. #endif
  104. volatile int stop_flag;
  105. recv_info_t recv_info;
  106. send_info_t send_info;
  107. int screen_img_id;
  108. int photo_img_id;
  109. int b_primary_server;
  110. int remote_video_rtp_port;
  111. int remote_video_desc;
  112. char remote_client_id[32];
  113. int connected;
  114. char local_pwd[KEY_LEN];
  115. char remote_pwd[KEY_LEN];
  116. RC4_KEY local_key;
  117. RC4_KEY remote_key;
  118. int remote_version;
  119. LARGE_INTEGER last_remote_active_time;
  120. LARGE_INTEGER last_local_active_time;
  121. screen_decoder_session_t *dec_session;
  122. };
  123. typedef int (*lpfn_cryptionfun)(unsigned char * out ,int outLen,const unsigned char * in,int inLen);
  124. static lpfn_cryptionfun decodestring = NULL;
  125. static lpfn_cryptionfun encodestring = NULL;
  126. static unsigned char seed_key []= {0x81,0x32,0x13,0xf5,0x29,0x3b,0x52,0x37,0x61,0x98,0x33,0x15,0x72,0x31,0xfe,0x34};
  127. static __inline unsigned int hash32_buf(const void *bf, size_t len, unsigned int hash)
  128. {
  129. const unsigned char *s = (const unsigned char*)bf;
  130. while (len-- != 0) /* "nemesi": k=257, r=r*257 */
  131. hash = hash * 257 + *s++;
  132. return (hash * 257);
  133. }
  134. static void generate_rand_key(char *key, int size)
  135. {
  136. int i;
  137. srand(GetTickCount()*33);
  138. for (i = 0; i < size; ++i) {
  139. key[i] = (char)(rand() & 0xff);
  140. }
  141. #ifdef RVC_OS_WIN
  142. srand(GetCurrentProcessId() * 33);
  143. #else
  144. srand(getpid() * 33);
  145. #endif
  146. for (i = 0; i < size; ++i) {
  147. key[i] ^= (char)(rand() & 0xff);
  148. }
  149. }
  150. static __inline unsigned int hash_key(const char *key, int size)
  151. {
  152. return hash32_buf(key, size, 0);
  153. }
  154. static __inline int check_hash(char *key, int size, int hash_code)
  155. {
  156. return hash32_buf(key, size, 0) == hash_code;
  157. }
  158. static __inline void GetTick(LARGE_INTEGER *last, LARGE_INTEGER *lt)
  159. {
  160. #ifdef RVC_OS_WIN
  161. DWORD dwNow = GetTickCount();
  162. if (last->LowPart > dwNow) {
  163. lt->LowPart = dwNow;
  164. lt->HighPart = last->HighPart + 1;
  165. } else {
  166. lt->LowPart = dwNow;
  167. lt->HighPart = last->HighPart;
  168. }
  169. #else
  170. DWORD dwNow = GetTickCount();
  171. if (last->u.LowPart > dwNow) {
  172. lt->u.LowPart = dwNow;
  173. lt->u.HighPart = last->u.HighPart + 1;
  174. }
  175. else {
  176. lt->u.LowPart = dwNow;
  177. lt->u.HighPart = last->u.HighPart;
  178. }
  179. #endif
  180. }
  181. void bizlog(bizchan_t *chan, const char* fmt, ...)
  182. {
  183. if (chan){
  184. va_list arg;
  185. va_start(arg, fmt);
  186. if (chan->cb.dbg) {
  187. (*chan->cb.dbg)(chan->cb.user_data, fmt, arg);
  188. }
  189. va_end(arg);
  190. }
  191. }
  192. BIZCHAN_API(int) bizchan_lib_init()
  193. {
  194. #ifdef RVC_OS_WIN
  195. WSADATA wsaData;
  196. return WSAStartup(0x0202, &wsaData);
  197. #else
  198. return 0;
  199. #endif
  200. }
  201. BIZCHAN_API(int) bizchan_lib_term()
  202. {
  203. #ifdef RVC_OS_WIN
  204. return WSACleanup();
  205. #else
  206. return 0;
  207. #endif
  208. }
  209. static int config_copy(bizchan_t* chan, const bizchan_config_t *src, bizchan_config_t *dst)
  210. {
  211. memcpy(dst, src, sizeof(bizchan_config_t));
  212. dst->proxy_server = strdup(src->proxy_server);
  213. if (src->bak_proxy_server != NULL) {
  214. dst->bak_proxy_server = strdup(src->bak_proxy_server);
  215. }
  216. if (src->session_id != NULL) {
  217. dst->session_id = strdup(src->session_id);
  218. }
  219. if (src->agent_id != NULL) {
  220. dst->agent_id = strdup(src->agent_id);
  221. }
  222. if (src->client_id != NULL) {
  223. dst->client_id = strdup(src->client_id);
  224. }
  225. return 0;
  226. }
  227. static int config_check(const bizchan_config_t *config)
  228. {
  229. if (!config->proxy_server)
  230. return -1;
  231. if (config->proxy_server_port <= 0 || config->proxy_server_port >= 0xffff)
  232. return -1;
  233. if (config->bak_proxy_server) {
  234. if (config->bak_proxy_server_port <= 0 || config->bak_proxy_server_port >= 0xffff)
  235. return -1;
  236. }
  237. if (!config->session_id)
  238. return -1;
  239. if (!config->agent_id)
  240. return -1;
  241. return 0;
  242. }
  243. static void config_free(bizchan_config_t *config)
  244. {
  245. free(config->proxy_server);
  246. free(config->bak_proxy_server);
  247. free(config->session_id);
  248. free(config->agent_id);
  249. free(config->client_id);
  250. }
  251. static int callback_check(const bizchan_callback_t *cb)
  252. {
  253. if (!cb->on_close)
  254. return -1;
  255. if (!cb->on_connect)
  256. return -1;
  257. if (!cb->on_recv_pkt)
  258. return -1;
  259. return 0;
  260. }
  261. static void invoke_on_connect(bizchan_t *chan, int error)
  262. {
  263. if (error == 0)
  264. chan->cb.on_connect(chan,
  265. error,
  266. chan->b_primary_server ? chan->config.proxy_server : chan->config.bak_proxy_server,
  267. chan->remote_video_rtp_port,
  268. chan->remote_video_desc,
  269. chan->remote_client_id,
  270. chan->cb.user_data);
  271. else
  272. chan->cb.on_connect(chan,
  273. error,
  274. NULL,
  275. 0,
  276. 0,
  277. NULL,
  278. chan->cb.user_data);
  279. }
  280. //static FILE *rx_log_fp = NULL;
  281. static void invoke_on_recv_pkt(bizchan_t *chan, int type, int sub_type, int id, const char *pkt, int pkt_size)
  282. {
  283. /*if (rx_log_fp == NULL) {
  284. rx_log_fp = fopen("c:\\rxlog.txt", "wt");
  285. fprintf(rx_log_fp, "===================\n");
  286. }
  287. {
  288. SYSTEMTIME st;
  289. GetLocalTime(&st);
  290. fprintf(rx_log_fp, "[%02d:%02d:%02d.%03d] type = %d, sub_type = %d, id = %d, pkt_size = %d, hash = %d\n",
  291. st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
  292. type, sub_type, id, pkt_size, hash32_buf(pkt, pkt_size, 0));
  293. fflush(rx_log_fp);
  294. }*/
  295. //Dbg(chan, "invoke_on_recv_pkt, type:%d, sub_type:%d, id:%d, pkt_size:%d", type, sub_type, id, pkt_size);
  296. if (type == ACM_TYPE_SRN) {
  297. int cat = ACM_SRN_CAT(sub_type);
  298. if (cat == ACM_SRN_ANS) {
  299. if (id == chan->screen_img_id) {
  300. if (pkt_size == 4)
  301. {
  302. int err;
  303. memcpy(&err, pkt, 4);
  304. chan->cb.on_recv_screen(chan, id, err, 0, 0, NULL, 0, chan->cb.user_data);
  305. }
  306. else
  307. {
  308. int size = 0;
  309. int width, height;
  310. int rc;
  311. char *dec_buf = NULL;
  312. rc = screen_decoder_session_decode(chan->dec_session, pkt, pkt_size, &width, &height, dec_buf, &size);
  313. if (rc == 0) {
  314. dec_buf = (char*)malloc(size);
  315. rc = screen_decoder_session_decode(chan->dec_session, pkt, pkt_size, &width, &height, dec_buf, &size);
  316. }
  317. if (rc == 0) {
  318. chan->cb.on_recv_screen(chan, id, 0, width, height, dec_buf, size, chan->cb.user_data);
  319. } else {
  320. chan->cb.on_recv_screen(chan, id, rc, 0, 0, NULL, 0, chan->cb.user_data);
  321. }
  322. if (dec_buf)
  323. free(dec_buf);
  324. }
  325. }
  326. } else
  327. {
  328. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  329. }
  330. } else if (type == ACM_TYPE_PHT) {
  331. int cat = ACM_PHT_CAT(sub_type);
  332. if (cat == ACM_PHT_ANS)
  333. {
  334. if (id == chan->photo_img_id) {
  335. if (pkt_size == 4) {
  336. int err;
  337. memcpy(&err, pkt, 4);
  338. chan->cb.on_recv_photo(chan, id, err, 0, 0, NULL, 0, chan->cb.user_data);
  339. } else {
  340. jpeg2k_raw_image raw_image = {0};
  341. jpeg2k_coded_image codec_image = {0};
  342. int rc;
  343. codec_image.data = (unsigned char*)pkt;
  344. codec_image.len = pkt_size;
  345. rc = jpeg2k_decode(&raw_image, &codec_image);
  346. if (rc == 0) {
  347. 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);
  348. jpeg2k_decode_free(&raw_image);
  349. } else {
  350. chan->cb.on_recv_photo(chan, id, rc, 0, 0, NULL, 0, chan->cb.user_data);
  351. }
  352. }
  353. }
  354. } else {
  355. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  356. }
  357. } else if (type == ACM_TYPE_SYNC) {
  358. if (chan->winsync_on_recv_cb) {
  359. chan->winsync_on_recv_cb(sub_type, pkt, pkt_size, chan->winsync_user_data);
  360. }
  361. //同时上报应用层,用于应用层判断采用哪种同步方式(Sivilight或者chrome H5)
  362. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  363. } else if (type == ACM_TYPE_MODE) {
  364. if (chan->mode_cb) {
  365. chan->mode_cb(TRUE, chan->winsync_user_data);
  366. }
  367. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  368. } else if (type == ACM_TYPE_PING) {
  369. //..... remote ping, nothing todo
  370. } else {
  371. chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
  372. }
  373. }
  374. static void invoke_on_close(bizchan_t *chan)
  375. {
  376. if (chan->cb.on_close) {
  377. chan->cb.on_close(chan, chan->cb.user_data);
  378. }
  379. }
  380. static void invoke_on_destroy(bizchan_t *chan)
  381. {
  382. if (chan->cb.on_destroy) {
  383. chan->cb.on_destroy(chan, chan->cb.user_data);
  384. }
  385. }
  386. static FILE *fp = NULL;
  387. static int on_recv2(bizchan_t *chan, SOCKET conn)
  388. {
  389. int n;
  390. char buf[0x10000+sizeof(acm_hdr)];
  391. if (fp == NULL) {
  392. #ifdef RVC_OS_WIN
  393. fp = fopen ("g:\\rx.dat", "wb");
  394. #else
  395. fp = fopen("/home/rx.dat", "wb");
  396. #endif
  397. }
  398. do {
  399. n = recv(conn, buf, sizeof(buf), 0);
  400. if (n > 0) {
  401. fwrite(buf, 1, n, fp);
  402. fflush(fp);
  403. }
  404. } while (n > 0);
  405. #ifdef RVC_OS_WIN
  406. return (n == 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
  407. #else
  408. return (n == 0 || (errno == EWOULDBLOCK) || (errno == EINTR)) ? 0 : -1;
  409. #endif
  410. }
  411. static int on_recv(bizchan_t *chan, SOCKET conn)
  412. {
  413. recv_info_t *ri = &chan->recv_info;
  414. int n;
  415. int result = 0;
  416. do {
  417. n = recv(conn, ri->buf+ri->offset, ri->buf_len-ri->offset, 0);
  418. if (n > 0) {
  419. int i = 0;
  420. ri->offset += n;
  421. GetTick(&chan->last_remote_active_time, &chan->last_remote_active_time);
  422. while (ri->offset-i >= sizeof(acm_hdr)) {
  423. acm_hdr *hdr = (acm_hdr*)&ri->buf[i];
  424. //Dbg(chan, "on_recv, i:%d offset:%d, recv_length:%d", i, ri->offset, n);
  425. //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);
  426. if (hdr->length == 0) {
  427. //printf("broken");
  428. }
  429. if (ri->offset-i >= hdr->length+sizeof(acm_hdr)) {
  430. if (hdr->encrypt)
  431. {
  432. int dec_length = hdr->length;
  433. char *dec_buf = (char*)malloc(hdr->length);
  434. 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);
  435. if (sm4_dec_result != 0){
  436. bizlog(chan, "DecStrWithSM4_ECB failed, type:%u, sub_type:%u, length:%lu", hdr->type, hdr->sub_type, hdr->length);
  437. RC4_set_key(&chan->remote_key, sizeof(chan->remote_pwd), (unsigned char*)chan->remote_pwd);
  438. RC4(&chan->remote_key, hdr->length, (const unsigned char*)(&hdr->data[0]), (unsigned char*)dec_buf);
  439. dec_length = hdr->length;
  440. }
  441. if (hdr->compress)
  442. {
  443. int len = (int)qlz_size_decompressed(dec_buf);
  444. char *unzip_buf = (char*)malloc(len);
  445. len = qlz_decompress(dec_buf, unzip_buf, &ri->decompress_state);
  446. if (check_hash(unzip_buf, len, hdr->hash))
  447. {
  448. invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
  449. }
  450. else {
  451. 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);
  452. }
  453. free(unzip_buf);
  454. } else {
  455. //sm4解密后hdr->length长度与内容长度不一致,采用dec_length变量
  456. if (check_hash(dec_buf, dec_length, hdr->hash)) {
  457. invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, dec_buf, dec_length);
  458. }
  459. else {
  460. 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);
  461. }
  462. }
  463. free(dec_buf);
  464. } else {
  465. if (hdr->compress) {
  466. int len = (int)qlz_size_decompressed((const char *)&hdr->data[0]);
  467. char *unzip_buf = (char*)malloc(len);
  468. len = qlz_decompress((const char*)&hdr->data[0], unzip_buf, &ri->decompress_state);
  469. if (check_hash(unzip_buf, len, hdr->hash)) {
  470. invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
  471. }
  472. else {
  473. 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);
  474. }
  475. free(unzip_buf);
  476. } else {
  477. if (check_hash((char*)&hdr->data[0], hdr->length, hdr->hash)) {
  478. invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, (const char*)&hdr->data[0], hdr->length);
  479. }
  480. else {
  481. bizlog(chan, "uncompress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu", hdr->type, hdr->sub_type, hdr->length, hdr->hash);
  482. }
  483. }
  484. }
  485. i += hdr->length+sizeof(acm_hdr);
  486. } else {
  487. break;
  488. }
  489. }
  490. if (i != ri->offset) {
  491. memmove(&ri->buf[0], &ri->buf[i], ri->offset-i);
  492. }
  493. ri->offset -= i;
  494. if (ri->offset == ri->buf_len) { // double large
  495. ri->buf_len = 2 * ri->buf_len;
  496. ri->buf = (char *)realloc(ri->buf, ri->buf_len);
  497. }
  498. }
  499. } while (n > 0);
  500. #ifdef RVC_OS_WIN
  501. return (n == 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
  502. #else
  503. //recv ==0,对端断开
  504. if (n == 0) {
  505. result = -1;
  506. }
  507. else {
  508. result = (n < 0 || (errno == EWOULDBLOCK) || (errno == EINTR) || (errno == EAGAIN)) ? 0 : -1;
  509. }
  510. //bizlog(chan, "on_recv n:%d, result:%d, errno:%d", n, result, errno);
  511. return result;
  512. #endif
  513. }
  514. static int on_send(bizchan_t *chan, SOCKET conn)
  515. {
  516. send_info_t *si = &chan->send_info;
  517. int n = 1;//默认为1
  518. int result = -1;
  519. #ifdef RVC_OS_WIN
  520. EnterCriticalSection(&si->lock);
  521. #else
  522. pthread_mutex_lock(&si->lock);
  523. #endif
  524. if (!ListEntry_IsEmpty(&si->send_list)) {
  525. do {
  526. send_buf_node *t = CONTAINING_RECORD(ListEntry_GetHead(&si->send_list), send_buf_node, entry);
  527. if (t->need_encrypt) {
  528. //SM4加密,密文会比明文长16字节
  529. int enc_length = t->left + sizeof(acm_hdr)+16;
  530. acm_hdr *hdr = (acm_hdr*)t->buf;
  531. char *enc_buf = (char*)malloc(t->left+sizeof(acm_hdr) + 16);
  532. //version为2代表支持国密,采用SM4加密
  533. if(chan->remote_version != 1){
  534. 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);
  535. hdr->length = enc_length;
  536. t->left = enc_length + sizeof(acm_hdr);
  537. //Dbg(chan, "enc_length:%d", enc_length);
  538. } else {
  539. RC4_set_key(&chan->local_key, sizeof(chan->local_pwd), (unsigned char*)chan->local_pwd);
  540. RC4(&chan->local_key, t->left, (const unsigned char*)(&hdr->data[0]), (unsigned char*)(enc_buf+sizeof(acm_hdr)));
  541. }
  542. memcpy(enc_buf, hdr, sizeof(acm_hdr));
  543. free(t->buf);
  544. t->buf = enc_buf;
  545. t->need_encrypt = 0;
  546. }
  547. n = send(conn, t->buf+t->sended, t->left, 0);
  548. //bizlog(chan, "on_send n:%d, t->sended:%d, t->left:%d", n, t->sended, t->left);
  549. if (n > 0) {
  550. //char tmp[32];
  551. //sprintf(tmp, "send out %d bytes!\n", n);
  552. //OutputDebugStringA(tmp);
  553. t->left -= n;
  554. t->sended += n;
  555. if (t->left == 0) {
  556. ListEntry_DeleteNode(&t->entry);
  557. free(t->buf);
  558. free(t);
  559. }
  560. GetTick(&chan->last_local_active_time, &chan->last_local_active_time);
  561. }
  562. } while (n > 0 && !ListEntry_IsEmpty(&si->send_list));
  563. }
  564. #ifdef RVC_OS_WIN
  565. LeaveCriticalSection(&si->lock);
  566. return (n >= 0 || (GetLastError() == WSAEWOULDBLOCK)) ? 0 : -1;
  567. #else
  568. pthread_mutex_unlock(&si->lock);
  569. if (n > 0) {
  570. result = 0;
  571. }
  572. else if (n < 0){
  573. if ((errno == EWOULDBLOCK) || (errno == EINTR) || (errno == EAGAIN)) {
  574. result = 0;
  575. }
  576. }
  577. return result;
  578. #endif
  579. }
  580. static void on_close(bizchan_t *chan)
  581. {
  582. invoke_on_close(chan);
  583. }
  584. #ifdef RVC_OS_WIN
  585. static int prepare_socket(SOCKET s, HANDLE evt)
  586. {
  587. BOOL opt = TRUE;
  588. int rc;
  589. rc = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
  590. opt = TRUE;
  591. if (rc == 0)
  592. rc = setsockopt(s, SOL_SOCKET, SO_DONTLINGER, (char*)&opt, sizeof(opt));
  593. if (rc == 0)
  594. rc = WSAEventSelect(s, evt, FD_CONNECT | FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE);
  595. return rc;
  596. }
  597. static void dump_exception(PEXCEPTION_POINTERS ExceptionInfo)
  598. {
  599. char tmp[MAX_PATH];
  600. HANDLE hDumpFile;
  601. sprintf(tmp, ".\\bizchan_%d.dmp", GetCurrentProcessId());
  602. hDumpFile = CreateFileA( tmp, GENERIC_READ | GENERIC_WRITE,
  603. 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  604. if( ( hDumpFile != NULL ) && ( hDumpFile != INVALID_HANDLE_VALUE ) )
  605. {
  606. MINIDUMP_EXCEPTION_INFORMATION mdei;
  607. MINIDUMP_TYPE mdt;
  608. mdei.ThreadId = GetCurrentThreadId();
  609. mdei.ExceptionPointers = ExceptionInfo;
  610. mdei.ClientPointers = FALSE;
  611. mdt = MiniDumpWithFullMemory;
  612. MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
  613. hDumpFile, mdt, (ExceptionInfo != 0) ? &mdei : 0, 0, 0 );
  614. CloseHandle( hDumpFile );
  615. }
  616. }
  617. #endif
  618. #ifdef RVC_OS_WIN
  619. static void process(bizchan_t *chan)
  620. {
  621. SOCKET conn = INVALID_SOCKET;
  622. struct sockaddr_in addr = {0};
  623. int rc;
  624. HANDLE evts[2] = {chan->evt, NULL};
  625. evts[1] = WSACreateEvent();
  626. // try connect to primary proxy server
  627. addr.sin_family = AF_INET;
  628. addr.sin_port = htons(chan->config.proxy_server_port);
  629. addr.sin_addr.s_addr = inet_addr(chan->config.proxy_server);
  630. chan->b_primary_server = TRUE;
  631. conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  632. if (conn == INVALID_SOCKET)
  633. goto on_error;
  634. rc = prepare_socket(conn, evts[1]);
  635. if (rc != 0)
  636. goto on_error;
  637. rc = connect(conn, (struct sockaddr*)&addr, sizeof(addr));
  638. if (rc == -1 && WSAGetLastError() == WSAEWOULDBLOCK) {
  639. rc = 0;
  640. }
  641. if (rc == -1 && chan->config.bak_proxy_server && strlen(chan->config.bak_proxy_server)) { // try connect to back proxy server
  642. closesocket(conn);
  643. conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  644. if (conn == INVALID_SOCKET)
  645. goto on_error;
  646. WSAResetEvent(evts[1]);
  647. rc = prepare_socket(conn, evts[1]);
  648. if (rc != 0)
  649. goto on_error;
  650. addr.sin_port = htons(chan->config.bak_proxy_server_port);
  651. addr.sin_addr.s_addr = inet_addr(chan->config.bak_proxy_server);
  652. chan->b_primary_server = 0;
  653. rc = connect(conn, (struct sockaddr*)&addr, sizeof(addr));
  654. if (rc == -1 && WSAGetLastError() == WSAEWOULDBLOCK) {
  655. rc = 0;
  656. }
  657. }
  658. if (rc == -1)
  659. goto on_error;
  660. if (rc == 0)
  661. {
  662. proxy_ack_hdr ack_hdr;
  663. int ack_hdr_recv_bytes = 0;
  664. lpfn_cryptionfun encodefun = encodestring;
  665. lpfn_cryptionfun decodefun = decodestring;
  666. if (1 == chan->config.crypt_type){
  667. encodefun = encodestring_mobile;
  668. decodefun = decodestring_mobile;
  669. }
  670. while (!chan->stop_flag && !chan->connected)
  671. { // wait until connected
  672. DWORD dwRet = WaitForMultipleObjects(2, evts, FALSE, MAX_TIMEOUT);
  673. if (dwRet == WAIT_OBJECT_0)
  674. {
  675. WSAResetEvent(evts[0]);
  676. } else if (dwRet == WAIT_OBJECT_0+1)
  677. {
  678. int error = 0;
  679. WSANETWORKEVENTS netevents;
  680. if (WSAEnumNetworkEvents(conn, evts[1], &netevents) != SOCKET_ERROR)
  681. {
  682. if (netevents.lNetworkEvents & FD_CONNECT)
  683. {
  684. if (netevents.iErrorCode[FD_CONNECT_BIT])
  685. error = netevents.iErrorCode[FD_CONNECT_BIT];
  686. }
  687. if (error == 0)
  688. {
  689. if (netevents.lNetworkEvents & FD_WRITE)
  690. {
  691. error = netevents.iErrorCode[FD_WRITE_BIT];
  692. if (error == 0) {
  693. int enc_length = KEY_LEN;
  694. proxy_hdr hdr = {0};
  695. hdr.tag[0] = 'A';
  696. hdr.tag[1] = 'C';
  697. hdr.tag[2] = 'M';
  698. hdr.version = ACM_PROTOCOL_VERSION;
  699. generate_rand_key(chan->local_pwd, KEY_LEN/2);
  700. //等待全部升级后再采用SM4加密
  701. #if ENCRYPT_CHINA
  702. EncWithSM4_ECB(seed_key, (unsigned char*)&chan->local_pwd[0], KEY_LEN / 2,
  703. (unsigned char*)&hdr.encrypt_key[0], &enc_length);
  704. bizlog(chan, "%s","use SM4 password_crypt_type");
  705. #else
  706. encodefun((unsigned char*)&hdr.encrypt_key[0], sizeof(hdr.encrypt_key), (unsigned char*)&chan->local_pwd[0], sizeof(chan->local_pwd));
  707. Dbg(chan, "use old password_crypt_type");
  708. #endif
  709. hdr.encrypt_keyhash = hash_key(chan->local_pwd, sizeof(chan->local_pwd));
  710. memset(hdr.callee_id, ' ', sizeof(hdr.callee_id));
  711. memset(hdr.caller_id, ' ', sizeof(hdr.caller_id));
  712. memset(hdr.client_id, ' ', sizeof(hdr.client_id));
  713. strncpy(&hdr.callee_id[0], chan->config.agent_id, sizeof(hdr.callee_id)-1);
  714. strncpy(&hdr.caller_id[0], chan->config.session_id, sizeof(hdr.caller_id)-1);
  715. if (chan->config.client_id) {
  716. strncpy(&hdr.client_id[0], chan->config.client_id, sizeof(hdr.client_id)-1);
  717. } else {
  718. hdr.client_id[0] = 0;
  719. }
  720. hdr.rtp_port = chan->config.video.rtp_port;
  721. hdr.media_desc = chan->config.video.desc;
  722. if (send(conn, (char*)&hdr, sizeof(hdr), 0) != sizeof(hdr)) {
  723. error = -1;
  724. }
  725. }
  726. }
  727. }
  728. if (error == 0)
  729. {
  730. if (netevents.lNetworkEvents & FD_CLOSE)
  731. error = -1;
  732. }
  733. if (error == 0)
  734. {
  735. if (netevents.lNetworkEvents & FD_READ)
  736. {
  737. error = netevents.iErrorCode[FD_READ_BIT];
  738. if (error == 0)
  739. {
  740. int t;
  741. do
  742. {
  743. t = recv(conn, (char*)&ack_hdr + ack_hdr_recv_bytes, sizeof(ack_hdr)-ack_hdr_recv_bytes, 0);
  744. if (t > 0) {
  745. ack_hdr_recv_bytes += t;
  746. if (ack_hdr_recv_bytes == sizeof(ack_hdr)) {
  747. int dec_length = KEY_LEN;
  748. int result = DecWithSM4_ECB(seed_key,
  749. (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key),
  750. (unsigned char*)&chan->remote_pwd[0], &dec_length);
  751. bizlog(chan, "use SM4 Decode password result:%d", result);
  752. if(result != 0){
  753. result = decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
  754. bizlog(chan, "use old Decode password result:%d", result);
  755. }
  756. if (check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash)) {
  757. chan->remote_video_rtp_port = ack_hdr.rtp_port;
  758. chan->remote_video_desc = ack_hdr.media_desc;
  759. memcpy(chan->remote_client_id, ack_hdr.client_id, sizeof(chan->remote_client_id));
  760. chan->remote_version = ack_hdr.version;
  761. bizlog(chan, "remote_acm_version:%d", chan->remote_version);
  762. chan->connected = TRUE;
  763. break;
  764. } else {
  765. error = -1;
  766. }
  767. }
  768. }
  769. }
  770. while (t > 0 && error == 0);
  771. if (t <= 0 && (WSAGetLastError() != WSAEWOULDBLOCK))
  772. error = -1;
  773. }
  774. }
  775. }
  776. if (error != 0)
  777. goto on_error;
  778. }
  779. } else {
  780. goto on_error;
  781. }
  782. }
  783. }
  784. assert(conn != INVALID_SOCKET);
  785. if (chan->connected)
  786. {
  787. invoke_on_connect(chan, 0);
  788. chan->recv_info.offset = 0;
  789. rc = on_recv(chan, conn);
  790. if (rc)
  791. {
  792. on_close(chan);
  793. goto on_error;
  794. }
  795. while (!chan->stop_flag)
  796. {
  797. DWORD dwRet = WaitForMultipleObjects(2, evts, FALSE, 1000);
  798. if (dwRet == WAIT_OBJECT_0)
  799. {
  800. WSAResetEvent(chan->evt);
  801. rc = on_send(chan, conn);
  802. if (rc != 0)
  803. break;
  804. }
  805. else if (dwRet == WAIT_OBJECT_0+1)
  806. {
  807. WSANETWORKEVENTS netevents;
  808. if (WSAEnumNetworkEvents(conn, evts[1], &netevents) != SOCKET_ERROR)
  809. {
  810. if (netevents.lNetworkEvents & FD_READ)
  811. {
  812. rc = on_recv(chan, conn);
  813. }
  814. if (netevents.lNetworkEvents & FD_WRITE) {
  815. rc = on_send(chan, conn);
  816. }
  817. if (rc || (netevents.lNetworkEvents & FD_CLOSE)) {
  818. break;
  819. }
  820. }
  821. }
  822. else if (dwRet == WAIT_TIMEOUT)
  823. {
  824. LARGE_INTEGER now;
  825. GetTick(&chan->last_remote_active_time, &now);
  826. if (now.QuadPart - chan->last_remote_active_time.QuadPart >= PING_INTERVAL) {
  827. GetTick(&chan->last_local_active_time, &now);
  828. if (now.QuadPart - chan->last_local_active_time.QuadPart >= PING_INTERVAL) {
  829. bizchan_post_pkt(chan, ACM_TYPE_PING, 0, 0, 0, 0, NULL, 0);
  830. }
  831. }
  832. } else {
  833. goto on_error;
  834. }
  835. }
  836. on_close(chan);
  837. }
  838. on_error:
  839. if (!chan->connected) {
  840. invoke_on_connect(chan, -1); // connect failed!
  841. } else {
  842. //....
  843. bizlog(chan, "%s", "connected, and error!");
  844. }
  845. if (conn != INVALID_SOCKET)
  846. closesocket(conn);
  847. WSACloseEvent(evts[1]);
  848. }
  849. #else
  850. static void do_shake_send(bizchan_t* chan, SOCKET conn, int* error) {
  851. proxy_hdr hdr = { 0 };
  852. proxy_ack_hdr ack_hdr;
  853. int ack_hdr_recv_bytes = 0;
  854. lpfn_cryptionfun encodefun = encodestring;
  855. lpfn_cryptionfun decodefun = decodestring;
  856. int enc_length = KEY_LEN;
  857. hdr.tag[0] = 'A';
  858. hdr.tag[1] = 'C';
  859. hdr.tag[2] = 'M';
  860. hdr.version = ACM_PROTOCOL_VERSION;
  861. generate_rand_key(chan->local_pwd, KEY_LEN / 2);
  862. //等待全部升级后再采用SM4加密
  863. #if ENCRYPT_CHINA
  864. EncWithSM4_ECB(seed_key, (unsigned char*)&chan->local_pwd[0], KEY_LEN / 2,
  865. (unsigned char*)&hdr.encrypt_key[0], &enc_length);
  866. //bizlog(chan, "use SM4 password_crypt_type");
  867. #else
  868. encodefun((unsigned char*)&hdr.encrypt_key[0], sizeof(hdr.encrypt_key), (unsigned char*)&chan->local_pwd[0], sizeof(chan->local_pwd));
  869. bizlog(chan, "use old password_crypt_type");
  870. #endif
  871. hdr.encrypt_keyhash = hash_key(chan->local_pwd, sizeof(chan->local_pwd));
  872. memset(hdr.callee_id, ' ', sizeof(hdr.callee_id));
  873. memset(hdr.caller_id, ' ', sizeof(hdr.caller_id));
  874. memset(hdr.client_id, ' ', sizeof(hdr.client_id));
  875. strncpy(&hdr.callee_id[0], chan->config.agent_id, sizeof(hdr.callee_id) - 1);
  876. strncpy(&hdr.caller_id[0], chan->config.session_id, sizeof(hdr.caller_id) - 1);
  877. if (chan->config.client_id) {
  878. strncpy(&hdr.client_id[0], chan->config.client_id, sizeof(hdr.client_id) - 1);
  879. }
  880. else {
  881. hdr.client_id[0] = 0;
  882. }
  883. hdr.rtp_port = chan->config.video.rtp_port;
  884. hdr.media_desc = chan->config.video.desc;
  885. if (send(conn, (char*)&hdr, sizeof(hdr), 0) != sizeof(hdr)) {
  886. *error = -1;
  887. }
  888. }
  889. static void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
  890. int t;
  891. proxy_ack_hdr ack_hdr;
  892. int ack_hdr_recv_bytes = 0;
  893. lpfn_cryptionfun encodefun = encodestring;
  894. lpfn_cryptionfun decodefun = decodestring;
  895. do
  896. {
  897. t = recv(conn, (char*)&ack_hdr + ack_hdr_recv_bytes, sizeof(ack_hdr) - ack_hdr_recv_bytes, 0);
  898. if (t > 0) {
  899. //snprintf(buffer, 128, "do_shake_recv t:%d, ack_hdr_recv_bytes:%d, sizeof(ack_hdr):%d", t, ack_hdr_recv_bytes, sizeof(ack_hdr));
  900. //chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
  901. ack_hdr_recv_bytes += t;
  902. if (ack_hdr_recv_bytes == sizeof(ack_hdr)) {
  903. int dec_length = KEY_LEN;
  904. int result = DecWithSM4_ECB(seed_key,
  905. (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key),
  906. (unsigned char*)&chan->remote_pwd[0], &dec_length);
  907. //bizlog(chan, "use SM4 Decode password result:%d", result);
  908. if (result != 0) {
  909. result = decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
  910. //bizlog(chan, "use old Decode password result:%d", result);
  911. }
  912. if (check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash)) {
  913. chan->remote_video_rtp_port = ack_hdr.rtp_port;
  914. chan->remote_video_desc = ack_hdr.media_desc;
  915. memcpy(chan->remote_client_id, ack_hdr.client_id, sizeof(chan->remote_client_id));
  916. chan->remote_version = ack_hdr.version;
  917. //bizlog(chan, "remote_acm_version:%d", chan->remote_version);
  918. chan->connected = TRUE;
  919. break;
  920. }
  921. else {
  922. *error = -1;
  923. bizlog(chan, "do_shake_recv check_hash failed");
  924. }
  925. }
  926. }
  927. } while (t > 0 && *error == 0);
  928. #ifdef RVC_OS_WIN
  929. if (t <= 0 && (WSAGetLastError() != WSAEWOULDBLOCK))
  930. *error = -1;
  931. #else
  932. if (t <= 0 && ((errno != EWOULDBLOCK) || (errno != EINTR) || (errno != EAGAIN))) {
  933. *error = -1;
  934. bizlog(chan, "do_shake_recv errno:%d", errno);
  935. bizlog(chan, "do_shake_recv t<=0 failed");
  936. }
  937. #endif
  938. }
  939. static void build_fd_sets(SOCKET conn, int evt, fd_set* read_fds, fd_set* write_fds, fd_set* except_fds)
  940. {
  941. FD_ZERO(read_fds);
  942. FD_SET(conn, read_fds);
  943. FD_SET(evt, read_fds);
  944. FD_ZERO(write_fds);
  945. FD_SET(conn, write_fds);
  946. FD_ZERO(except_fds);
  947. FD_SET(conn, except_fds);
  948. FD_SET(evt, except_fds);
  949. }
  950. static int set_socket_noblock(SOCKET socket) {
  951. #ifdef RVC_OS_WIN
  952. {
  953. //windows将socket设置成非阻塞的方式
  954. unsigned long on = 1;
  955. if (ioctlsocket(socket, FIONBIO, &on) < 0) {
  956. return -1;
  957. }
  958. }
  959. #else
  960. {
  961. //linux将socket设置成非阻塞的方式
  962. //将新socket设置为non-blocking
  963. int oldflag = fcntl(socket, F_GETFL, 0);
  964. int newflag = oldflag | O_NONBLOCK;
  965. if (fcntl(socket, F_SETFL, newflag) == -1) {
  966. return -1;
  967. }
  968. }
  969. #endif
  970. return 0;
  971. }
  972. SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
  973. {
  974. struct sockaddr_in addrSrv = { 0 };
  975. SOCKET m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  976. if (m_hSocket == INVALID_SOCKET)
  977. return INVALID_SOCKET;
  978. if (set_socket_noblock(m_hSocket) != 0)
  979. {
  980. #ifdef RVC_OS_WIN
  981. closesocket(m_hSocket);
  982. #else
  983. close(m_hSocket);
  984. #endif
  985. bizlog(chan, "connect_server set_socket_noblock failed");
  986. }
  987. addrSrv.sin_family = AF_INET;
  988. addrSrv.sin_addr.s_addr = inet_addr(server);
  989. addrSrv.sin_port = htons(port);
  990. int ret = connect(m_hSocket, (struct sockaddr*)&addrSrv, sizeof(addrSrv));
  991. if (ret == 0) {
  992. //bizlog(chan, "connect_server connect success 1.");
  993. return m_hSocket;
  994. }
  995. #ifdef RVC_OS_WIN
  996. //windows下检测WSAEWOULDBLOCK
  997. if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) {
  998. closesocket(m_hSocket);
  999. return INVALID_SOCKET;
  1000. }
  1001. #else
  1002. //linux下需要检测EINPROGRESS和EINTR
  1003. if (ret < 0 && (errno != EINPROGRESS && errno != EINTR)) {
  1004. close(m_hSocket);
  1005. bizlog(chan, "connect_server connect failed, errno: %d", errno);
  1006. return INVALID_SOCKET;
  1007. }
  1008. #endif
  1009. fd_set writeset;
  1010. FD_ZERO(&writeset);
  1011. FD_SET(m_hSocket, &writeset);
  1012. struct timeval tv;
  1013. tv.tv_sec = timeout;
  1014. //可以利用tv_usec做更小精度的超时设置
  1015. tv.tv_usec = 0;
  1016. if (select(m_hSocket + 1, NULL, &writeset, NULL, &tv) != 1) {
  1017. #ifdef RVC_OS_WIN
  1018. closesocket(m_hSocket);
  1019. #else
  1020. close(m_hSocket);
  1021. #endif
  1022. bizlog(chan, "connect_server connect timeout.");
  1023. return INVALID_SOCKET;
  1024. }
  1025. //bizlog(chan, "connect_server connect success 2.");
  1026. return m_hSocket;
  1027. }
  1028. static void process(bizchan_t* chan) {
  1029. int error = 0;
  1030. //connect
  1031. chan->b_primary_server = TRUE;
  1032. SOCKET conn = connect_server(chan, chan->config.proxy_server, chan->config.proxy_server_port, 5);
  1033. if (conn == INVALID_SOCKET && chan->config.bak_proxy_server && strlen(chan->config.bak_proxy_server)) { // try connect to back proxy server
  1034. chan->b_primary_server = FALSE;
  1035. conn = connect_server(chan, chan->config.bak_proxy_server, chan->config.bak_proxy_server_port, 5);
  1036. }
  1037. //send recv
  1038. fd_set read_fds;
  1039. fd_set write_fds;
  1040. fd_set except_fds;
  1041. int maxfd = max(conn, chan->evt[0]);
  1042. if (conn == INVALID_SOCKET) {
  1043. error = -1;
  1044. }
  1045. else {
  1046. #if 0
  1047. do_shake_send(chan, conn, &error);
  1048. if (error != 0) {
  1049. Dbg(chan, 0, "do_shake_send failed");
  1050. goto on_error;
  1051. }
  1052. do_shake_recv(chan, conn, &error);
  1053. if (error != 0) {
  1054. Dbg(chan, 0, "do_shake_recv failed");
  1055. goto on_error;
  1056. }
  1057. #else
  1058. do_shake_send(chan, conn, &error);
  1059. if (error != 0) {
  1060. bizlog(chan, "do_shake_send failed");
  1061. goto on_error;
  1062. }
  1063. while (!chan->stop_flag && !chan->connected) {
  1064. struct timeval tv;
  1065. tv.tv_sec = MAX_TIMEOUT / 1000;
  1066. //可以利用tv_usec做更小精度的超时设置
  1067. tv.tv_usec = 0;
  1068. // Select() updates fd_set's, so we need to build fd_set's before each select()call.
  1069. build_fd_sets(conn, chan->evt[0], &read_fds, &write_fds, &except_fds);
  1070. int activity = select(maxfd + 1, &read_fds, NULL, &except_fds, &tv);
  1071. if (activity == -1) {
  1072. perror("select()");
  1073. bizlog(chan, "process shake select -1");
  1074. goto on_error;
  1075. }
  1076. else if (activity == 0) {
  1077. // timeout
  1078. //printf("select() returns 0.\n");
  1079. //bizlog(chan, "process shake select 0");
  1080. goto on_error;
  1081. }else {
  1082. /* All fd_set's should be checked. */
  1083. if (FD_ISSET(conn, &read_fds)) {
  1084. do_shake_recv(chan, conn, &error);
  1085. }
  1086. if (FD_ISSET(chan->evt[0], &read_fds)) {
  1087. //读取管道数据并丢弃,管道主要用于唤醒select
  1088. char pipe_read_buffer[4];
  1089. int n = read(chan->evt[0], pipe_read_buffer, 4);
  1090. if (n < 0) {
  1091. bizlog(chan, "process shake pipe read < 0");
  1092. }
  1093. }
  1094. if (FD_ISSET(conn, &except_fds)) {
  1095. error = -1;
  1096. }
  1097. if (error != 0) {
  1098. goto on_error;
  1099. }
  1100. }
  1101. }
  1102. #endif
  1103. }
  1104. if (chan->connected)
  1105. {
  1106. char buffer[128] = {0};
  1107. int rc;
  1108. invoke_on_connect(chan, 0);
  1109. chan->recv_info.offset = 0;
  1110. while (!chan->stop_flag)
  1111. {
  1112. struct timeval tv;
  1113. tv.tv_sec = 1;
  1114. //可以利用tv_usec做更小精度的超时设置
  1115. tv.tv_usec = 0;
  1116. // Select() updates fd_set's, so we need to build fd_set's before each select()call.
  1117. build_fd_sets(conn, chan->evt[0], &read_fds, &write_fds, &except_fds);
  1118. int activity = select(maxfd + 1, &read_fds, NULL, &except_fds, &tv);
  1119. if (activity == -1) {
  1120. perror("select()");
  1121. bizlog(chan, "chan select() error.");
  1122. goto on_error;
  1123. }
  1124. else if (activity == 0) {
  1125. // timeout
  1126. //printf("select() returns 0, timeout.\n");
  1127. //Dbg(chan, 0, "select() returns 0, timeout.");
  1128. LARGE_INTEGER now;
  1129. GetTick(&chan->last_remote_active_time, &now);
  1130. if (now.QuadPart - chan->last_remote_active_time.QuadPart >= PING_INTERVAL) {
  1131. GetTick(&chan->last_local_active_time, &now);
  1132. if (now.QuadPart - chan->last_local_active_time.QuadPart >= PING_INTERVAL) {
  1133. bizchan_post_pkt(chan, ACM_TYPE_PING, 0, 0, 0, 0, NULL, 0);
  1134. }
  1135. }
  1136. //huchen add for send_list is not null
  1137. #ifdef RVC_OS_WIN
  1138. EnterCriticalSection(&chan->send_info.lock);
  1139. #else
  1140. pthread_mutex_lock(&chan->send_info.lock);
  1141. #endif
  1142. if (!ListEntry_IsEmpty(&chan->send_info.send_list)) {
  1143. write(chan->evt[1], "post", sizeof("post"));
  1144. }
  1145. #ifdef RVC_OS_WIN
  1146. LeaveCriticalSection(&chan->send_info.lock);
  1147. #else
  1148. pthread_mutex_unlock(&chan->send_info.lock);
  1149. #endif
  1150. }else {
  1151. //Dbg(chan, 0, "select() returns read_fds.");
  1152. /* All fd_set's should be checked. */
  1153. if (FD_ISSET(conn, &read_fds)) {
  1154. //Dbg(chan, 0, "select() returns read_fds conn.");
  1155. rc = on_recv(chan, conn);
  1156. if (rc != 0)
  1157. break;
  1158. }
  1159. if (FD_ISSET(chan->evt[0], &read_fds)) {
  1160. //Dbg(chan, 0, "select() returns read_fds fife.");
  1161. //读取管道数据并丢弃,管道主要用于唤醒select
  1162. char pipe_read_buffer[4];
  1163. int n = read(chan->evt[0], pipe_read_buffer, 4);
  1164. if (n >= 0) {
  1165. rc = on_send(chan, conn);
  1166. if (rc != 0)
  1167. break;
  1168. }
  1169. else {
  1170. bizlog(chan, "pipe read < 0");
  1171. }
  1172. }
  1173. if (FD_ISSET(conn, &except_fds)) {
  1174. bizlog(chan, "select() except_fds set.");
  1175. error = -1;
  1176. }
  1177. if (error != 0) {
  1178. goto on_error;
  1179. }
  1180. }
  1181. }
  1182. on_close(chan);
  1183. }
  1184. on_error:
  1185. if (!chan->connected) {
  1186. invoke_on_connect(chan, -1); // connect failed!
  1187. }
  1188. else {
  1189. //....
  1190. //OutputDebugStringA("connected, and error!");
  1191. bizlog(chan, "connected, and error!");
  1192. }
  1193. if (conn != INVALID_SOCKET) {
  1194. #ifdef RVC_OS_WIN
  1195. closesocket(conn);
  1196. #else
  1197. close(conn);
  1198. #endif
  1199. }
  1200. }
  1201. #endif
  1202. #ifdef RVC_OS_WIN
  1203. static unsigned int __stdcall work_proc(LPVOID arg)
  1204. #else
  1205. static void* work_proc(void* arg)
  1206. #endif
  1207. {
  1208. bizchan_t *chan = (bizchan_t *)arg;
  1209. #ifdef RVC_OS_WIN
  1210. __try {
  1211. process(chan);
  1212. } __except(dump_exception(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {
  1213. //....
  1214. }
  1215. #else
  1216. //bizlog(chan, "work_proc start");
  1217. process(chan);
  1218. #endif
  1219. return 0;
  1220. }
  1221. #ifdef RVC_OS_WIN
  1222. static int init_decode_func(const bizchan_config_t* config, const bizchan_callback_t* cb)
  1223. {
  1224. int ret = -1;
  1225. if (!encodestring) {
  1226. HMODULE hInst = LoadLibraryA("acmstrenc.dll");
  1227. if (hInst) {
  1228. encodestring = (lpfn_cryptionfun)GetProcAddress(hInst, "encodestring");
  1229. }
  1230. if (!encodestring)
  1231. return ret;
  1232. }
  1233. if (!decodestring) {
  1234. HMODULE hInst = LoadLibraryA("acmstrdec.dll");
  1235. if (hInst) {
  1236. decodestring = (lpfn_cryptionfun)GetProcAddress(hInst, "decodestring");
  1237. }
  1238. if (!decodestring)
  1239. return ret;
  1240. }
  1241. if (!encodestring_mobile) {
  1242. HMODULE hInst = LoadLibraryA("acmstrenc_mobile.dll");
  1243. if (hInst) {
  1244. encodestring_mobile = (lpfn_cryptionfun)GetProcAddress(hInst, "encodestring");
  1245. }
  1246. if (!encodestring_mobile)
  1247. return ret;
  1248. }
  1249. if (!decodestring_mobile) {
  1250. HMODULE hInst = LoadLibraryA("acmstrdec_mobile.dll");
  1251. if (hInst) {
  1252. decodestring_mobile = (lpfn_cryptionfun)GetProcAddress(hInst, "decodestring");
  1253. }
  1254. if (!decodestring_mobile)
  1255. return ret;
  1256. }
  1257. if (encodestring && decodestring && encodestring_mobile && decodestring_mobile){
  1258. ret = 0;
  1259. }
  1260. return ret;
  1261. }
  1262. #else
  1263. static int init_decode_func(const bizchan_config_t* config, const bizchan_callback_t* cb)
  1264. {
  1265. int ret = -1;
  1266. if (!encodestring) {
  1267. HMODULE hInst = LoadLibraryA("libacmstrenc.so");
  1268. if (hInst) {
  1269. encodestring = (lpfn_cryptionfun)GetProcAddress(hInst, "encodestring");
  1270. }
  1271. if (!encodestring) {
  1272. return ret;
  1273. }
  1274. }
  1275. if (!decodestring) {
  1276. HMODULE hInst = LoadLibraryA("libacmstrdec.so");
  1277. if (hInst) {
  1278. decodestring = (lpfn_cryptionfun)GetProcAddress(hInst, "decodestring");
  1279. }
  1280. if (!decodestring)
  1281. return ret;
  1282. }
  1283. if (encodestring && decodestring) {
  1284. ret = 0;
  1285. }
  1286. return ret;
  1287. }
  1288. #endif
  1289. BIZCHAN_API(int) bizchan_create(const bizchan_config_t *config, const bizchan_callback_t *cb, bizchan_t **p_chan)
  1290. {
  1291. bizchan_t *chan = NULL;
  1292. if (-1 == init_decode_func(config, cb)){
  1293. return -1;
  1294. }
  1295. if (!config || !p_chan) {
  1296. return -1;
  1297. }
  1298. if (config_check(config) != 0) {
  1299. return -1;
  1300. }
  1301. if (callback_check(cb) != 0) {
  1302. return -1;
  1303. }
  1304. chan = (bizchan_t*)malloc(sizeof(bizchan_t));
  1305. if (!chan)
  1306. goto on_error;
  1307. memset(chan, 0, sizeof(bizchan_t));
  1308. chan->recv_info.buf_len = DEFAULT_RX_BUF_SIZE;
  1309. chan->recv_info.buf = (char*)malloc(chan->recv_info.buf_len);
  1310. if (!chan->recv_info.buf)
  1311. goto on_error;
  1312. memcpy(&chan->cb, cb, sizeof(bizchan_callback_t));
  1313. if (config_copy(chan, config, &chan->config) != 0)
  1314. goto on_error;
  1315. ListEntry_InitHead(&chan->send_info.send_list);
  1316. #ifdef RVC_OS_WIN
  1317. InitializeCriticalSection(&chan->send_info.lock);
  1318. #else
  1319. pthread_mutexattr_init(&chan->send_info.attr);
  1320. pthread_mutexattr_settype(&chan->send_info.attr, PTHREAD_MUTEX_RECURSIVE);
  1321. pthread_mutex_init(&chan->send_info.lock, &chan->send_info.attr);
  1322. #endif
  1323. screen_decoder_session_create(&chan->dec_session);
  1324. #ifdef RVC_OS_WIN
  1325. chan->evt = WSACreateEvent();
  1326. if (!chan->evt)
  1327. goto on_error;
  1328. #else
  1329. pipe(chan->evt);
  1330. #endif
  1331. *p_chan = chan;
  1332. return 0;
  1333. on_error:
  1334. bizchan_destroy(chan);
  1335. return -1;
  1336. }
  1337. BIZCHAN_API(int) bizchan_winsync_set_cb(bizchan_t *chan, OnRecvPacket pkt_cb, OnMode mode_cb, void *user_data)
  1338. {
  1339. chan->winsync_on_recv_cb = pkt_cb;
  1340. chan->mode_cb = mode_cb;
  1341. chan->winsync_user_data = user_data;
  1342. return 0;
  1343. }
  1344. BIZCHAN_API(void) bizchan_destroy(bizchan_t *chan)
  1345. {
  1346. if (chan) {
  1347. #ifdef RVC_OS_WIN
  1348. if (chan->evt) {
  1349. WSACloseEvent(chan->evt);
  1350. chan->evt = NULL;
  1351. }
  1352. #else
  1353. close(chan->evt[0]);
  1354. close(chan->evt[1]);
  1355. #endif
  1356. invoke_on_destroy(chan);
  1357. #ifdef RVC_OS_WIN
  1358. assert(chan->work_thread == NULL);
  1359. #endif
  1360. config_free(&chan->config);
  1361. if (chan->recv_info.buf)
  1362. free(chan->recv_info.buf);
  1363. if (chan->recv_info.unzip_buf)
  1364. free(chan->recv_info.unzip_buf);
  1365. while (!ListEntry_IsEmpty(&chan->send_info.send_list)) {
  1366. send_buf_node *p = CONTAINING_RECORD(ListEntry_RemoveListHead(&chan->send_info.send_list), send_buf_node, entry);
  1367. free(p->buf);
  1368. free(p);
  1369. }
  1370. #ifdef RVC_OS_WIN
  1371. DeleteCriticalSection(&chan->send_info.lock);
  1372. #else
  1373. pthread_mutex_destroy(&chan->send_info.lock);
  1374. #endif
  1375. if (chan->dec_session) {
  1376. screen_decoder_session_destroy(chan->dec_session);
  1377. chan->dec_session = NULL;
  1378. }
  1379. free(chan);
  1380. }
  1381. }
  1382. BIZCHAN_API(void) bizchan_set_tag(bizchan_t *chan, void *tag)
  1383. {
  1384. chan->tag = tag;
  1385. }
  1386. BIZCHAN_API(void*) bizchan_get_tag(bizchan_t *chan)
  1387. {
  1388. return chan->tag;
  1389. }
  1390. BIZCHAN_API(int) bizchan_start_connect(bizchan_t *chan)
  1391. {
  1392. DWORD threadId;
  1393. if (!chan) {
  1394. return -1;
  1395. }
  1396. if (chan->work_thread) {
  1397. bizlog(chan, "work_thread exsit!!!");
  1398. return -1;
  1399. }
  1400. #ifdef RVC_OS_WIN
  1401. WSAResetEvent(chan->evt);
  1402. #endif
  1403. //bizlog(chan, "bizchan_start_connect 2");
  1404. chan->stop_flag = 0;
  1405. chan->connected = 0;
  1406. #ifdef RVC_OS_WIN
  1407. chan->work_thread = (HANDLE)_beginthreadex(NULL, 0, &work_proc, (LPVOID)chan, 0, (unsigned int*)&threadId);
  1408. if (!chan->work_thread) {
  1409. return -1;
  1410. }
  1411. #else
  1412. int err = pthread_create(&chan->work_thread, NULL, work_proc, chan);
  1413. if (0 == err) {
  1414. //bizlog(chan, "create work thread success, %lu.", chan->work_thread);
  1415. }
  1416. else {
  1417. bizlog(chan, "create work thread failed.");
  1418. }
  1419. #endif // RVC_OS_WIN
  1420. // we now return, when connected, on_connect will invoked in work_proc thread
  1421. //bizlog(chan, "bizchan_start_connect success");
  1422. return 0;
  1423. }
  1424. BIZCHAN_API(int) bizchan_start_close(bizchan_t *chan)
  1425. {
  1426. bizlog(chan, "bizchan_start_close");
  1427. chan->stop_flag = 1;
  1428. #ifdef RVC_OS_WIN
  1429. WSASetEvent(chan->evt);
  1430. #else
  1431. write(chan->evt[1], "stop", sizeof("stop"));
  1432. #endif
  1433. return 0;
  1434. }
  1435. BIZCHAN_API(int) bizchan_close(bizchan_t *chan)
  1436. {
  1437. #ifdef RVC_OS_WIN
  1438. if (chan->work_thread) {
  1439. WaitForSingleObject(chan->work_thread, INFINITE);
  1440. CloseHandle(chan->work_thread);
  1441. chan->work_thread = NULL;
  1442. }
  1443. #else
  1444. pthread_join(chan->work_thread, NULL);
  1445. chan->work_thread = 0;
  1446. #endif // RVC_OS_WIN
  1447. return 0;
  1448. }
  1449. //static FILE *tx_log_fp = NULL;
  1450. 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)
  1451. {
  1452. send_buf_node *t;
  1453. if (!chan->connected) {
  1454. return -1;
  1455. }
  1456. t = (send_buf_node *)malloc(sizeof(send_buf_node));
  1457. //if (!tx_log_fp) {
  1458. // tx_log_fp = fopen("c:\\txlog.txt", "wt");
  1459. // fprintf(tx_log_fp, "===================\n");
  1460. //}
  1461. //{
  1462. // SYSTEMTIME st;
  1463. // GetLocalTime(&st);
  1464. // fprintf(tx_log_fp, "[%02d:%02d:%02d.%03d] type = %d, compress = %d, sub_type = %d, id = %d, pkt_size = %d, hash = %d\n",
  1465. // st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
  1466. // type, compress, sub_type, id, pkt_size, hash32_buf(pkt, pkt_size, 0));
  1467. // fflush(tx_log_fp);
  1468. //}
  1469. if (type == ACM_TYPE_SRN) {
  1470. int cat = ACM_SRN_CAT(sub_type);
  1471. if (cat == ACM_SRN_REQ) {
  1472. chan->screen_img_id = id;
  1473. }
  1474. } else if (type == ACM_TYPE_PHT) {
  1475. int cat = ACM_PHT_CAT(sub_type);
  1476. if (cat == ACM_PHT_REQ) {
  1477. chan->photo_img_id = id;
  1478. }
  1479. }
  1480. if (!compress || pkt_size == 0) {
  1481. acm_hdr *hdr;
  1482. t->buf = (char*)malloc(pkt_size + sizeof(acm_hdr));
  1483. t->left = pkt_size + sizeof(acm_hdr);
  1484. t->sended = 0;
  1485. hdr = (acm_hdr*)&t->buf[0];
  1486. hdr->compress = 0;
  1487. hdr->length = pkt_size;
  1488. hdr->sub_type = sub_type;
  1489. hdr->type = type;
  1490. hdr->id = id;
  1491. hdr->encrypt = !!encrypt;
  1492. hdr->hash = hash_key(pkt, pkt_size);
  1493. memcpy(&hdr->data[0], pkt, pkt_size);
  1494. t->need_encrypt = encrypt;
  1495. }
  1496. else {
  1497. qlz_state_compress state_compress;
  1498. acm_hdr *hdr;
  1499. int new_pkt_size;
  1500. t->buf = (char*)malloc(2*pkt_size + sizeof(acm_hdr) + 16);
  1501. hdr = (acm_hdr *)&t->buf[0];
  1502. new_pkt_size = (int)qlz_compress(pkt, (char*)&hdr->data[0], pkt_size, &state_compress);
  1503. if (new_pkt_size < pkt_size) {
  1504. hdr->compress = 1;
  1505. hdr->length = new_pkt_size;
  1506. t->left = new_pkt_size + sizeof(acm_hdr);
  1507. } else {
  1508. hdr->compress = 0;
  1509. hdr->length = pkt_size;
  1510. memcpy(&hdr->data[0], pkt, pkt_size);
  1511. t->left = pkt_size + sizeof(acm_hdr);
  1512. }
  1513. hdr->type = type;
  1514. hdr->id = id;
  1515. hdr->sub_type = sub_type;
  1516. hdr->encrypt = !!encrypt;
  1517. hdr->hash = hash_key(pkt, pkt_size);
  1518. t->sended = 0;
  1519. t->need_encrypt = encrypt;
  1520. }
  1521. #ifdef RVC_OS_WIN
  1522. EnterCriticalSection(&chan->send_info.lock);
  1523. ListEntry_AddTail(&chan->send_info.send_list, &t->entry);
  1524. LeaveCriticalSection(&chan->send_info.lock);
  1525. WSASetEvent(chan->evt);
  1526. #else
  1527. pthread_mutex_lock(&chan->send_info.lock);
  1528. ListEntry_AddTail(&chan->send_info.send_list, &t->entry);
  1529. pthread_mutex_unlock(&chan->send_info.lock);
  1530. write(chan->evt[1], "post", sizeof("post"));
  1531. #endif
  1532. return 0;
  1533. }
  1534. BIZCHAN_API(int) bizchan_winsync_send(bizchan_t *chan, int sub_type, const void *buf, int size)
  1535. {
  1536. if (chan && chan->work_thread) {
  1537. return bizchan_post_pkt(chan, ACM_TYPE_SYNC, 1, sub_type, 1, 0, (const char*)buf, size);
  1538. } else {
  1539. return -1;
  1540. }
  1541. }