sp_sps.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #include "precompile.h"
  2. #include "sp_sps.h"
  3. #include "sp_def.h"
  4. #include "sp_logwithlinkforc.h"
  5. #include "memutil.h"
  6. #define SILVERLIGHT_POLICY_PORT 943
  7. #define MAX_TIMEOUT 30000
  8. static const char *req_policy = "<policy-file-request/>";
  9. static const int req_policy_len = 22;
  10. static const char *res_policy =
  11. "<?xml version=\"1.0\" encoding =\"utf-8\"?>\r\n"
  12. "<access-policy>\r\n"
  13. " <cross-domain-access>\r\n"
  14. " <policy>\r\n"
  15. " <allow-from>\r\n"
  16. " <domain uri=\"*\" />\r\n"
  17. " </allow-from>\r\n"
  18. " <grant-to>\r\n"
  19. " <socket-resource port=\"4502-4506\" protocol=\"tcp\" />\r\n"
  20. " </grant-to>\r\n"
  21. " </policy>\r\n"
  22. " </cross-domain-access>\r\n"
  23. "</access-policy>\r\n";
  24. static const int res_policy_len = 323;
  25. struct sp_sps_t
  26. {
  27. WSAEVENT evt_ready;
  28. int result;
  29. WSAEVENT evt_stop;
  30. HANDLE worker_thread;
  31. };
  32. static void __on_accept(SOCKET policy_fd)
  33. {
  34. struct sockaddr_in from_addr;
  35. int from_len = sizeof(from_addr);
  36. SOCKET conn_fd = accept(policy_fd, (struct sockaddr*)&from_addr, &from_len);
  37. u_long iMode = 0;
  38. int recved = 0;
  39. char req_buf[512];
  40. int buf_len = sizeof(req_buf);
  41. int sended = 0;
  42. int need_send = res_policy_len;
  43. BOOL opt;
  44. if (conn_fd == INVALID_SOCKET) {
  45. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "accept new connection fd failed!");
  46. return;
  47. }
  48. DbgWithLinkForC(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM, "accept from %s:%d", inet_ntoa(from_addr.sin_addr), ntohs(from_addr.sin_port));
  49. WSAEventSelect(conn_fd, NULL, 0);
  50. #ifdef _WIN32
  51. ioctlsocket(conn_fd, FIONBIO, &iMode);
  52. #else
  53. _ioctlsocket(conn_fd, FIONBIO, &iMode);
  54. #endif //_WIN32
  55. opt = TRUE;
  56. setsockopt(conn_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
  57. opt = TRUE;
  58. setsockopt(conn_fd, SOL_SOCKET, SO_DONTLINGER, (char*)&opt, sizeof(opt));
  59. while (recved < req_policy_len) {
  60. int t = recv(conn_fd, req_buf+recved, req_policy_len-recved, 0);
  61. if (t <= 0) {
  62. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "recv conn_fd failed! error:%d", WSAGetLastError());
  63. goto on_error;
  64. } else {
  65. recved += t;
  66. }
  67. }
  68. if (_strnicmp(req_policy, req_buf, req_policy_len) != 0) {
  69. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "warning: req_buf not equal to <policy-file-request/>!!!");
  70. goto on_error;
  71. }
  72. while (sended < need_send) {
  73. int t = send(conn_fd, res_policy+sended, res_policy_len-sended, 0);
  74. if (t <= 0) {
  75. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "send res policy failed!");
  76. goto on_error;
  77. } else {
  78. sended += t;
  79. }
  80. }
  81. shutdown(conn_fd, SD_BOTH);
  82. on_error:
  83. closesocket(conn_fd);
  84. }
  85. static const char *_GetFileName(const char *pszFilePath)
  86. {
  87. int i=strlen(pszFilePath);
  88. for( ; i>0 && pszFilePath[i-1]!='\\'; i--)NULL;
  89. return pszFilePath+i;
  90. }
  91. static unsigned int __stdcall __sps_worker_proc(void *arg)
  92. {
  93. sp_sps_t *sps = (sp_sps_t*)arg;
  94. WSAEVENT evt[2] = {sps->evt_stop};
  95. SOCKET fd = INVALID_SOCKET;
  96. struct sockaddr_in addr = {0};
  97. fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  98. if (fd == INVALID_SOCKET) {
  99. sps->result = -1;
  100. goto on_start_error;
  101. }
  102. addr.sin_family = AF_INET;
  103. addr.sin_port = htons(SILVERLIGHT_POLICY_PORT);
  104. addr.sin_addr.s_addr = htonl(INADDR_ANY); // only for debug
  105. //addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  106. if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) != 0 || listen(fd, 5) != 0) {
  107. sps->result = -1;
  108. goto on_start_error;
  109. }
  110. evt[1] = WSACreateEvent();
  111. WSAEventSelect(fd, evt[1], FD_ACCEPT | FD_CLOSE);
  112. sps->result = 0;
  113. WSASetEvent(sps->evt_ready);
  114. for(;;) {
  115. DWORD dwRet = WSAWaitForMultipleEvents(ARRAYSIZE(evt), &evt[0], FALSE, MAX_TIMEOUT, FALSE);
  116. if (dwRet == WSA_WAIT_EVENT_0) {
  117. break; // stop
  118. } else if (dwRet == WSA_WAIT_EVENT_0+1) {
  119. WSANETWORKEVENTS netevents;
  120. if (WSAEnumNetworkEvents(fd, evt[1], &netevents) != SOCKET_ERROR) {
  121. if (netevents.lNetworkEvents & FD_ACCEPT) {
  122. if (netevents.iErrorCode[FD_ACCEPT_BIT] == 0) {
  123. __on_accept(fd);
  124. }
  125. }
  126. if (netevents.lNetworkEvents & FD_CLOSE) {
  127. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "accept closed! err %d %s %d", WSAGetLastError(), _GetFileName(__FILE__), __LINE__);
  128. break;
  129. }
  130. } else {
  131. DbgWithLinkForC(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM, "WSAGetLastError %d %s %d", WSAGetLastError(), _GetFileName(__FILE__), __LINE__);
  132. }
  133. } else if (dwRet == WSA_WAIT_TIMEOUT) {
  134. continue;
  135. } else {
  136. break;
  137. }
  138. }
  139. on_start_error:
  140. if (evt[1]) {
  141. WSAEventSelect(fd, evt[1], 0);
  142. WSACloseEvent(evt[1]);
  143. evt[1] = NULL;
  144. }
  145. if (fd != INVALID_SOCKET) {
  146. closesocket(fd);
  147. }
  148. WSASetEvent(sps->evt_ready);
  149. return sps->result;
  150. }
  151. int sp_sps_create(sp_sps_t **p_sps)
  152. {
  153. sp_sps_t *sps = MALLOC_T(sp_sps_t);
  154. sps->evt_ready = WSACreateEvent();
  155. sps->evt_stop = WSACreateEvent();
  156. sps->worker_thread = NULL;
  157. *p_sps = sps;
  158. return 0;
  159. }
  160. int sp_sps_start(sp_sps_t *sps)
  161. {
  162. WSAResetEvent(sps->evt_ready);
  163. WSAResetEvent(sps->evt_stop);
  164. sps->result = 0;
  165. sps->worker_thread = (HANDLE)_beginthreadex(NULL, 0, &__sps_worker_proc, sps, 0, NULL);
  166. if (sps->worker_thread) {
  167. WSAEVENT evt[1] = {sps->evt_ready};
  168. WSAWaitForMultipleEvents(1, &evt[0], FALSE, WSA_INFINITE, FALSE);
  169. if (sps->result != 0) {
  170. WaitForSingleObject(sps->worker_thread, INFINITE);
  171. CloseHandle(sps->worker_thread);
  172. sps->worker_thread = NULL;
  173. }
  174. return sps->result;
  175. } else {
  176. return Error_Resource;
  177. }
  178. }
  179. void sp_sps_destroy(sp_sps_t *sps)
  180. {
  181. WSACloseEvent(sps->evt_ready);
  182. WSACloseEvent(sps->evt_stop);
  183. free(sps);
  184. }
  185. void sp_sps_stop(sp_sps_t *sps)
  186. {
  187. WSASetEvent(sps->evt_stop);
  188. WaitForSingleObject(sps->worker_thread, INFINITE);
  189. CloseHandle(sps->worker_thread);
  190. sps->worker_thread = NULL;
  191. }