sp_sps.c 5.3 KB

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