No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SocketImpl.cpp 67KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427
  1. #include "il2cpp-config.h"
  2. #if !IL2CPP_USE_GENERIC_SOCKET_IMPL && IL2CPP_TARGET_WINDOWS && IL2CPP_SUPPORT_SOCKETS
  3. #include <time.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #include <sys/stat.h>
  8. #include "WindowsHelpers.h"
  9. #include <WinSock2.h>
  10. #include <WS2tcpip.h>
  11. #include <mswsock.h>
  12. #include "os/Error.h"
  13. #include "os/Socket.h"
  14. #include "os/ErrorCodes.h"
  15. #include "os/Win32/SocketImpl.h"
  16. #include "utils/Il2CppError.h"
  17. #include "utils/StringUtils.h"
  18. #include "utils/Memory.h"
  19. typedef int socklen_t;
  20. namespace il2cpp
  21. {
  22. namespace os
  23. {
  24. static bool is_loopback(int32_t family, uint8_t *addr)
  25. {
  26. if (family == AF_INET)
  27. return addr[0] == 127;
  28. #if IL2CPP_SUPPORT_IPV6
  29. else if (family == AF_INET6)
  30. return (IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr));
  31. #endif
  32. return false;
  33. }
  34. static struct in_addr *get_local_ips(int32_t family, int32_t *nips)
  35. {
  36. *nips = 0;
  37. return 0;
  38. }
  39. static bool hostent_get_info(struct hostent *he, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addresses)
  40. {
  41. if (he == NULL)
  42. return false;
  43. if (he->h_length != 4 || he->h_addrtype != AF_INET)
  44. return false;
  45. name.assign(he->h_name);
  46. for (int32_t i = 0; he->h_aliases[i] != NULL; ++i)
  47. aliases.push_back(he->h_aliases[i]);
  48. if (he->h_addrtype == AF_INET)
  49. {
  50. struct in_addr addr = {0};
  51. for (int32_t i = 0; he->h_addr_list[i] != NULL; ++i)
  52. {
  53. addr.s_addr = *(u_long*)he->h_addr_list[i];
  54. addresses.push_back(inet_ntoa(addr));
  55. }
  56. }
  57. return true;
  58. }
  59. static bool hostent_get_info_with_local_ips(struct hostent *he, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addresses)
  60. {
  61. int32_t i = 0;
  62. int32_t nlocal_in = 0;
  63. if (he != NULL)
  64. {
  65. if (he->h_length != 4 || he->h_addrtype != AF_INET)
  66. return false;
  67. name.assign(he->h_name);
  68. for (int32_t i = 0; he->h_aliases[i] != NULL; ++i)
  69. aliases.push_back(he->h_aliases[i]);
  70. }
  71. struct in_addr *local_in = get_local_ips(AF_INET, &nlocal_in);
  72. if (nlocal_in)
  73. {
  74. for (int32_t i = 0; i < nlocal_in; ++i)
  75. addresses.push_back(inet_ntoa(local_in[i]));
  76. free(local_in);
  77. }
  78. else if (he == NULL)
  79. {
  80. // If requesting "" and there are no other interfaces up, MS returns 127.0.0.1
  81. addresses.push_back("127.0.0.1");
  82. return true;
  83. }
  84. if (nlocal_in == 0 && he != NULL)
  85. {
  86. if (he->h_addrtype == AF_INET)
  87. {
  88. struct in_addr addr = {0};
  89. for (int32_t i = 0; he->h_addr_list[i] != NULL; ++i)
  90. {
  91. addr.s_addr = *(u_long*)he->h_addr_list[i];
  92. addresses.push_back(inet_ntoa(addr));
  93. }
  94. }
  95. }
  96. return true;
  97. }
  98. static int32_t convert_socket_flags(os::SocketFlags flags)
  99. {
  100. int32_t c_flags = 0;
  101. if (flags)
  102. {
  103. // Check if contains invalid flag values
  104. if (flags & ~(os::kSocketFlagsOutOfBand | os::kSocketFlagsMaxIOVectorLength | os::kSocketFlagsPeek | os::kSocketFlagsDontRoute | os::kSocketFlagsPartial))
  105. {
  106. return -1;
  107. }
  108. if (flags & os::kSocketFlagsOutOfBand)
  109. c_flags |= MSG_OOB;
  110. if (flags & os::kSocketFlagsPeek)
  111. c_flags |= MSG_PEEK;
  112. if (flags & os::kSocketFlagsDontRoute)
  113. c_flags |= MSG_DONTROUTE;
  114. // Ignore Partial - see bug 349688. Don't return -1, because
  115. // according to the comment in that bug ms runtime doesn't for
  116. // UDP sockets (this means we will silently ignore it for TCP
  117. // too)
  118. #ifdef MSG_MORE
  119. if (flags & os::kSocketFlagsPartial)
  120. c_flags |= MSG_MORE;
  121. #endif
  122. }
  123. return c_flags;
  124. }
  125. #if IL2CPP_SUPPORT_IPV6
  126. static void AddrinfoGetAddresses(struct addrinfo *info, std::string& name, bool add_local_ips,
  127. std::vector<std::string> &addr_list)
  128. {
  129. if (add_local_ips)
  130. {
  131. int nlocal_in = 0;
  132. int nlocal_in6 = 0;
  133. in_addr* local_in = (struct in_addr *)get_local_ips(AF_INET, &nlocal_in);
  134. in6_addr* local_in6 = (struct in6_addr *)get_local_ips(AF_INET6, &nlocal_in6);
  135. if (nlocal_in || nlocal_in6)
  136. {
  137. if (nlocal_in)
  138. {
  139. for (int i = 0; i < nlocal_in; i++)
  140. {
  141. char addr[16];
  142. inet_ntop(AF_INET, &local_in[i], addr, sizeof(addr));
  143. addr_list.push_back(std::string(addr));
  144. }
  145. }
  146. if (nlocal_in6)
  147. {
  148. for (int i = 0; i < nlocal_in6; i++)
  149. {
  150. char addr[48];
  151. const char* ret = inet_ntop(AF_INET6, &local_in6[i], addr, sizeof(addr));
  152. if (ret != NULL)
  153. addr_list.push_back(std::string(addr));
  154. }
  155. }
  156. }
  157. free(local_in);
  158. free(local_in6);
  159. }
  160. bool nameSet = false;
  161. for (addrinfo* ai = info; ai != NULL; ai = ai->ai_next)
  162. {
  163. const char *ret;
  164. char buffer[48]; /* Max. size for IPv6 */
  165. if ((ai->ai_family != PF_INET) && (ai->ai_family != PF_INET6))
  166. continue;
  167. if (ai->ai_family == PF_INET)
  168. ret = inet_ntop(ai->ai_family, (void*)&(((struct sockaddr_in*)ai->ai_addr)->sin_addr), buffer, 16);
  169. else
  170. ret = inet_ntop(ai->ai_family, (void*)&(((struct sockaddr_in6*)ai->ai_addr)->sin6_addr), buffer, 48);
  171. if (ret)
  172. addr_list.push_back(std::string(buffer));
  173. else
  174. addr_list.push_back(std::string());
  175. if (!nameSet)
  176. {
  177. if (ai->ai_canonname != NULL)
  178. name = std::string(ai->ai_canonname);
  179. else
  180. name = std::string();
  181. nameSet = true;
  182. }
  183. }
  184. }
  185. WaitStatus GetAddressInfo(const char* hostname, bool add_local_ips, std::string &name, std::vector<std::string> &addr_list)
  186. {
  187. addrinfo *info = NULL;
  188. addrinfo hints;
  189. memset(&hints, 0, sizeof(hints));
  190. // Here Mono inspects the ipv4Supported and ipv6Supported properties on the managed Socket class.
  191. // This seems to be unnecessary though, as we can use PF_UNSPEC in all cases, and getaddrinfo works.
  192. hints.ai_family = PF_UNSPEC;
  193. hints.ai_socktype = SOCK_STREAM;
  194. hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
  195. if (getaddrinfo(hostname, NULL, &hints, &info) == -1)
  196. return kWaitStatusFailure;
  197. AddrinfoGetAddresses(info, name, add_local_ips, addr_list);
  198. if (info)
  199. freeaddrinfo(info);
  200. if (name.empty())
  201. name.assign(hostname);
  202. return kWaitStatusSuccess;
  203. }
  204. #endif
  205. static WaitStatus GetHostByAddrIPv4(const std::string &address, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addr_list)
  206. {
  207. struct in_addr inaddr;
  208. if (inet_pton(AF_INET, address.c_str(), &inaddr) <= 0)
  209. return kWaitStatusFailure;
  210. struct hostent *he = gethostbyaddr((char*)&inaddr, sizeof(inaddr), AF_INET);
  211. if (he == NULL)
  212. {
  213. name = address;
  214. addr_list.push_back(name);
  215. return kWaitStatusSuccess;
  216. }
  217. return hostent_get_info(he, name, aliases, addr_list)
  218. ? kWaitStatusSuccess
  219. : kWaitStatusFailure;
  220. }
  221. WaitStatus SocketImpl::GetHostByAddr(const std::string &address, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addr_list)
  222. {
  223. #if IL2CPP_SUPPORT_IPV6
  224. struct sockaddr_in saddr;
  225. struct sockaddr_in6 saddr6;
  226. int32_t family;
  227. char hostname[1024] = { 0 };
  228. int flags = 0;
  229. if (inet_pton(AF_INET, address.c_str(), &saddr.sin_addr) <= 0)
  230. {
  231. /* Maybe an ipv6 address */
  232. if (inet_pton(AF_INET6, address.c_str(), &saddr6.sin6_addr) <= 0)
  233. {
  234. return kWaitStatusFailure;
  235. }
  236. else
  237. {
  238. family = AF_INET6;
  239. saddr6.sin6_family = AF_INET6;
  240. }
  241. }
  242. else
  243. {
  244. family = AF_INET;
  245. saddr.sin_family = AF_INET;
  246. }
  247. if (family == AF_INET)
  248. {
  249. return GetHostByAddrIPv4(address, name, aliases, addr_list);
  250. }
  251. else if (family == AF_INET6)
  252. {
  253. #if HAVE_SOCKADDR_IN6_SIN_LEN
  254. saddr6.sin6_len = sizeof(saddr6);
  255. #endif
  256. if (getnameinfo((struct sockaddr*)&saddr6, sizeof(saddr6),
  257. hostname, sizeof(hostname), NULL, 0,
  258. flags) != 0)
  259. {
  260. return kWaitStatusFailure;
  261. }
  262. }
  263. return GetAddressInfo(hostname, true, name, addr_list);
  264. #else
  265. return GetHostByAddrIPv4(address, name, aliases, addr_list);
  266. #endif
  267. }
  268. WaitStatus SocketImpl::GetHostByName(const std::string &host, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addresses)
  269. {
  270. char this_hostname[256] = {0};
  271. const char *hostname = host.c_str();
  272. bool add_local_ips = (*hostname == '\0');
  273. if (!add_local_ips && gethostname(this_hostname, sizeof(this_hostname)) != -1)
  274. {
  275. if (!strcmp(hostname, this_hostname))
  276. add_local_ips = true;
  277. }
  278. #if IL2CPP_SUPPORT_IPV6
  279. return GetAddressInfo(hostname, add_local_ips, name, addresses);
  280. #else
  281. struct hostent *he = NULL;
  282. if (*hostname)
  283. he = gethostbyname(hostname);
  284. if (*hostname && he == NULL)
  285. return kWaitStatusFailure;
  286. return (add_local_ips
  287. ? hostent_get_info_with_local_ips(he, name, aliases, addresses)
  288. : hostent_get_info(he, name, aliases, addresses))
  289. ? kWaitStatusSuccess
  290. : kWaitStatusFailure;
  291. #endif
  292. }
  293. WaitStatus SocketImpl::GetHostByName(const std::string &host, std::string &name, int32_t &family, std::vector<std::string> &aliases, std::vector<void*> &addr_list, int32_t &addr_size)
  294. {
  295. std::vector<std::string> addresses;
  296. WaitStatus result = GetHostByName(host, name, aliases, addresses);
  297. addr_size = sizeof(in_addr);
  298. family = AF_INET;
  299. for (std::vector<std::string>::iterator it = addresses.begin(); it != addresses.end(); ++it)
  300. {
  301. void* addressLocation = il2cpp::utils::Memory::Malloc(addr_size);
  302. in_addr address;
  303. if (inet_pton(family, it->c_str(), &address))
  304. {
  305. memcpy(addressLocation, &address.S_un.S_addr, addr_size);
  306. addr_list.push_back(addressLocation);
  307. }
  308. }
  309. return result;
  310. }
  311. void SocketImpl::Startup()
  312. {
  313. WSADATA wsadata;
  314. const int32_t ret = WSAStartup(MAKEWORD(2, 0), &wsadata);
  315. if (ret != 0)
  316. {
  317. exit(-1);
  318. }
  319. }
  320. void SocketImpl::Cleanup()
  321. {
  322. WSACleanup();
  323. }
  324. WaitStatus SocketImpl::GetHostName(std::string &name)
  325. {
  326. char hostname[256];
  327. int32_t ret = gethostname(hostname, sizeof(hostname));
  328. if (ret == -1)
  329. return kWaitStatusFailure;
  330. name.assign(hostname);
  331. return kWaitStatusSuccess;
  332. }
  333. SocketImpl::SocketImpl(ThreadStatusCallback thread_status_callback)
  334. : _is_valid(false)
  335. , _fd(-1)
  336. , _domain(-1)
  337. , _type(-1)
  338. , _protocol(-1)
  339. , _saved_error(kErrorCodeSuccess)
  340. , _still_readable(0)
  341. , _thread_status_callback(thread_status_callback)
  342. {
  343. }
  344. SocketImpl::~SocketImpl()
  345. {
  346. }
  347. static int32_t convert_address_family(AddressFamily family)
  348. {
  349. switch (family)
  350. {
  351. case kAddressFamilyUnspecified:
  352. return AF_UNSPEC;
  353. // NOTE(gab): not supported on Windows
  354. //case kAddressFamilyUnix:
  355. // return AF_UNIX;
  356. case kAddressFamilyInterNetwork:
  357. return AF_INET;
  358. case kAddressFamilyIpx:
  359. return AF_IPX;
  360. case kAddressFamilySna:
  361. return AF_SNA;
  362. case kAddressFamilyDecNet:
  363. return AF_DECnet;
  364. case kAddressFamilyAppleTalk:
  365. return AF_APPLETALK;
  366. #if IL2CPP_SUPPORT_IPV6
  367. case kAddressFamilyInterNetworkV6:
  368. return AF_INET6;
  369. #endif
  370. #ifdef AF_IRDA
  371. case kAddressFamilyIrda:
  372. return AF_IRDA;
  373. #endif
  374. default:
  375. break;
  376. }
  377. return -1;
  378. }
  379. static int32_t convert_socket_type(SocketType type)
  380. {
  381. switch (type)
  382. {
  383. case kSocketTypeStream:
  384. return SOCK_STREAM;
  385. case kSocketTypeDgram:
  386. return SOCK_DGRAM;
  387. case kSocketTypeRaw:
  388. return SOCK_RAW;
  389. case kSocketTypeRdm:
  390. return SOCK_RDM;
  391. case kSocketTypeSeqpacket:
  392. return SOCK_SEQPACKET;
  393. default:
  394. break;
  395. }
  396. return -1;
  397. }
  398. static int32_t convert_socket_protocol(ProtocolType protocol)
  399. {
  400. switch (protocol)
  401. {
  402. case kProtocolTypeIP:
  403. case kProtocolTypeIPv6:
  404. case kProtocolTypeIcmp:
  405. case kProtocolTypeIgmp:
  406. case kProtocolTypeGgp:
  407. case kProtocolTypeTcp:
  408. case kProtocolTypePup:
  409. case kProtocolTypeUdp:
  410. case kProtocolTypeIdp:
  411. case kProtocolTypeIcmpV6:
  412. // In this case the enum values map exactly.
  413. return (int32_t)protocol;
  414. default:
  415. break;
  416. }
  417. // Everything else in unsupported and unexpected
  418. return -1;
  419. }
  420. static int SocketExceptionFilter(unsigned int code)
  421. {
  422. // Sometimes, we call the socket functions and close the socket right after,
  423. // and in some rare cases, it throws EXCEPTION_INVALID_HANDLE SEH exception
  424. // rather than returning an error code. Although this is undocumented on MSDN,
  425. // it causes a crash just because it thinks we gave it an invalid handle.
  426. // We guard against it by wrapping every socket call with __try/__except
  427. if (code == EXCEPTION_INVALID_HANDLE)
  428. return EXCEPTION_CONTINUE_EXECUTION;
  429. return EXCEPTION_CONTINUE_SEARCH;
  430. }
  431. WaitStatus SocketImpl::Create(AddressFamily family, SocketType type, ProtocolType protocol)
  432. {
  433. _fd = -1;
  434. _is_valid = false;
  435. _still_readable = 1;
  436. _domain = convert_address_family(family);
  437. _type = convert_socket_type(type);
  438. _protocol = convert_socket_protocol(protocol);
  439. IL2CPP_ASSERT(_type != -1 && "Unsupported socket type");
  440. IL2CPP_ASSERT(_domain != -1 && "Unsupported address family");
  441. IL2CPP_ASSERT(_protocol != -1 && "Unsupported protocol type");
  442. _fd = socket(_domain, _type, _protocol);
  443. if (_fd == -1 && _domain == AF_INET && _type == SOCK_RAW && _protocol == 0)
  444. {
  445. // Retry with protocol == 4 (see bug #54565)
  446. _protocol = 4;
  447. _fd = socket(AF_INET, SOCK_RAW, 4);
  448. }
  449. if (_fd == -1)
  450. {
  451. StoreLastError();
  452. return kWaitStatusFailure;
  453. }
  454. _is_valid = true;
  455. return kWaitStatusSuccess;
  456. }
  457. WaitStatus SocketImpl::Create(SocketDescriptor fd, int32_t family, int32_t type, int32_t protocol)
  458. {
  459. _fd = fd;
  460. _is_valid = (fd != -1);
  461. _still_readable = 1;
  462. _domain = family;
  463. _type = type;
  464. _protocol = protocol;
  465. IL2CPP_ASSERT(_type != -1 && "Unsupported socket type");
  466. IL2CPP_ASSERT(_domain != -1 && "Unsupported address family");
  467. IL2CPP_ASSERT(_protocol != -1 && "Unsupported protocol type");
  468. return kWaitStatusSuccess;
  469. }
  470. WaitStatus SocketImpl::Close()
  471. {
  472. _saved_error = kErrorCodeSuccess;
  473. SOCKET fd = (SOCKET)_fd;
  474. if (_is_valid && fd != -1)
  475. {
  476. if (closesocket(fd) == -1)
  477. StoreLastError();
  478. }
  479. _fd = -1;
  480. _is_valid = false;
  481. _still_readable = 0;
  482. _domain = -1;
  483. _type = -1;
  484. _protocol = -1;
  485. return kWaitStatusSuccess;
  486. }
  487. WaitStatus SocketImpl::SetBlocking(bool blocking)
  488. {
  489. /*
  490. * block == TRUE/FALSE means we will block/not block.
  491. * But the ioctlsocket call takes TRUE/FALSE for non-block/block
  492. */
  493. u_long ioctl_socket_blocking = (u_long) !blocking;
  494. SOCKET fd = (SOCKET)_fd;
  495. if (fd == -1)
  496. {
  497. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  498. return kWaitStatusFailure;
  499. }
  500. int32_t ret = -1;
  501. __try
  502. {
  503. ret = ioctlsocket(fd, FIONBIO, &ioctl_socket_blocking);
  504. }
  505. __except (SocketExceptionFilter(GetExceptionCode()))
  506. {
  507. }
  508. if (ret == SOCKET_ERROR)
  509. {
  510. StoreLastError();
  511. return kWaitStatusFailure;
  512. }
  513. return kWaitStatusSuccess;
  514. }
  515. ErrorCode SocketImpl::GetLastError() const
  516. {
  517. return _saved_error;
  518. }
  519. void SocketImpl::StoreLastError()
  520. {
  521. const ErrorCode error = (ErrorCode)WSAGetLastError();
  522. Error::SetLastError(error);
  523. _saved_error = error;
  524. }
  525. void SocketImpl::StoreLastError(int32_t error_no)
  526. {
  527. const ErrorCode error = (ErrorCode)error_no;
  528. Error::SetLastError(error);
  529. _saved_error = error;
  530. }
  531. static void sockaddr_from_address(uint32_t address, uint16_t port, struct sockaddr *sa, socklen_t *sa_size)
  532. {
  533. struct sockaddr_in sa_in = {0};
  534. sa_in.sin_family = AF_INET;
  535. sa_in.sin_port = port;
  536. sa_in.sin_addr.s_addr = address;
  537. *sa_size = sizeof(struct sockaddr_in);
  538. *sa = *((struct sockaddr*)&sa_in);
  539. }
  540. #if IL2CPP_SUPPORT_IPV6
  541. static void sockaddr_from_address(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port, sockaddr_in6* sa, socklen_t *sa_size)
  542. {
  543. sa->sin6_family = AF_INET6;
  544. sa->sin6_port = port;
  545. memcpy(&sa->sin6_addr, &address[0], 16);
  546. sa->sin6_scope_id = scope;
  547. *sa_size = sizeof(struct sockaddr_in6);
  548. }
  549. #endif
  550. static AddressFamily convert_define_to_address_family(int32_t family)
  551. {
  552. switch (family)
  553. {
  554. case AF_UNSPEC:
  555. return kAddressFamilyUnspecified;
  556. case AF_UNIX:
  557. return kAddressFamilyUnix;
  558. case AF_INET:
  559. return kAddressFamilyInterNetwork;
  560. #ifdef AF_IPX
  561. case AF_IPX:
  562. return kAddressFamilyIpx;
  563. #endif
  564. #ifdef AF_SNA
  565. case AF_SNA:
  566. return kAddressFamilySna;
  567. #endif
  568. #ifdef AF_DECnet
  569. case AF_DECnet:
  570. return kAddressFamilyDecNet;
  571. #endif
  572. #ifdef AF_APPLETALK
  573. case AF_APPLETALK:
  574. return kAddressFamilyAppleTalk;
  575. #endif
  576. #ifdef AF_INET6
  577. case AF_INET6:
  578. return kAddressFamilyInterNetworkV6;
  579. #endif
  580. #ifdef AF_IRDA
  581. case AF_IRDA:
  582. return kAddressFamilyIrda;
  583. #endif
  584. default:
  585. break;
  586. }
  587. return kAddressFamilyError;
  588. }
  589. static bool socketaddr_to_endpoint_info(const struct sockaddr *address, socklen_t address_len, EndPointInfo &info)
  590. {
  591. info.family = convert_define_to_address_family(address->sa_family);
  592. if (info.family == os::kAddressFamilyInterNetwork)
  593. {
  594. const struct sockaddr_in *address_in = (const struct sockaddr_in *)address;
  595. info.data.inet.port = ntohs(address_in->sin_port);
  596. info.data.inet.address = ntohl(address_in->sin_addr.s_addr);
  597. return true;
  598. }
  599. // NOTE(gab): kAddressFamilyUnix not supported on Windows
  600. //if (info.family == os::kAddressFamilyUnix)
  601. //{
  602. // for (int32_t i = 0; i < address_len; i++)
  603. // info.data.path[i] = address->sa_data[i];
  604. // return true;
  605. //}
  606. #if IL2CPP_SUPPORT_IPV6
  607. if (info.family == os::kAddressFamilyInterNetworkV6)
  608. {
  609. const struct sockaddr_in6 *address_in = (const struct sockaddr_in6 *)address;
  610. uint16_t port = ntohs(address_in->sin6_port);
  611. info.data.raw[2] = (port >> 8) & 0xff;
  612. info.data.raw[3] = port & 0xff;
  613. for (int i = 0; i < 16; i++)
  614. info.data.raw[i + 8] = address_in->sin6_addr.s6_addr[i];
  615. info.data.raw[24] = address_in->sin6_scope_id & 0xff;
  616. info.data.raw[25] = (address_in->sin6_scope_id >> 8) & 0xff;
  617. info.data.raw[26] = (address_in->sin6_scope_id >> 16) & 0xff;
  618. info.data.raw[27] = (address_in->sin6_scope_id >> 24) & 0xff;
  619. return true;
  620. }
  621. #endif
  622. return false;
  623. }
  624. WaitStatus SocketImpl::Bind(const char *path)
  625. {
  626. // NOTE(gab): not supported on Windows.
  627. return kWaitStatusFailure;
  628. }
  629. WaitStatus SocketImpl::Bind(const char *address, uint16_t port)
  630. {
  631. struct sockaddr sa = {0};
  632. socklen_t sa_size = 0;
  633. sockaddr_from_address(inet_addr(address), htons(port), &sa, &sa_size);
  634. SOCKET fd = (SOCKET)_fd;
  635. if (fd == -1)
  636. {
  637. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  638. return kWaitStatusFailure;
  639. }
  640. int bindResult = -1;
  641. __try
  642. {
  643. bindResult = bind(fd, &sa, sa_size);
  644. }
  645. __except (SocketExceptionFilter(GetExceptionCode()))
  646. {
  647. }
  648. if (bindResult == -1)
  649. {
  650. StoreLastError();
  651. return kWaitStatusFailure;
  652. }
  653. return kWaitStatusSuccess;
  654. }
  655. WaitStatus SocketImpl::Bind(uint32_t address, uint16_t port)
  656. {
  657. struct sockaddr sa = {0};
  658. socklen_t sa_size = 0;
  659. sockaddr_from_address(htonl(address), htons(port), &sa, &sa_size);
  660. SOCKET fd = (SOCKET)_fd;
  661. if (fd == -1)
  662. {
  663. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  664. return kWaitStatusFailure;
  665. }
  666. int bindResult = -1;
  667. __try
  668. {
  669. bindResult = bind(fd, &sa, sa_size);
  670. }
  671. __except (SocketExceptionFilter(GetExceptionCode()))
  672. {
  673. }
  674. if (bindResult == -1)
  675. {
  676. StoreLastError();
  677. return kWaitStatusFailure;
  678. }
  679. return kWaitStatusSuccess;
  680. }
  681. WaitStatus SocketImpl::Bind(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port)
  682. {
  683. struct sockaddr_in6 sa = { 0 };
  684. socklen_t sa_size = 0;
  685. sockaddr_from_address(address, scope, htons(port), &sa, &sa_size);
  686. if (bind((SOCKET)_fd, (sockaddr*)&sa, sa_size) == -1)
  687. {
  688. StoreLastError();
  689. return kWaitStatusFailure;
  690. }
  691. return kWaitStatusSuccess;
  692. }
  693. WaitStatus SocketImpl::ConnectInternal(struct sockaddr *sa, int32_t sa_size)
  694. {
  695. SOCKET fd = (SOCKET)_fd;
  696. if (fd == -1)
  697. {
  698. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  699. return kWaitStatusFailure;
  700. }
  701. __try
  702. {
  703. if (connect(fd, sa, (socklen_t)sa_size) != -1)
  704. return kWaitStatusSuccess;
  705. if (errno != EINTR)
  706. {
  707. StoreLastError();
  708. return kWaitStatusFailure;
  709. }
  710. struct pollfd fds = { 0 };
  711. fds.fd = fd;
  712. fds.events = POLLOUT;
  713. while (WSAPoll(&fds, 1, -1) == -1)
  714. {
  715. if (errno != EINTR)
  716. {
  717. StoreLastError();
  718. return kWaitStatusFailure;
  719. }
  720. }
  721. int32_t so_error = 0;
  722. socklen_t len = sizeof(so_error);
  723. if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&so_error, &len) == -1)
  724. {
  725. StoreLastError();
  726. return kWaitStatusFailure;
  727. }
  728. if (so_error != 0)
  729. {
  730. StoreLastError(so_error);
  731. return kWaitStatusFailure;
  732. }
  733. }
  734. __except (SocketExceptionFilter(GetExceptionCode()))
  735. {
  736. SetLastError(kWSAeshutdown);
  737. return kWaitStatusFailure;
  738. }
  739. return kWaitStatusSuccess;
  740. }
  741. WaitStatus SocketImpl::Connect(const char *path)
  742. {
  743. // NOTE(gab): not supported on Windows.
  744. return kWaitStatusFailure;
  745. }
  746. WaitStatus SocketImpl::Connect(uint32_t address, uint16_t port)
  747. {
  748. struct sockaddr sa = {0};
  749. socklen_t sa_size = 0;
  750. sockaddr_from_address(htonl(address), htons(port), &sa, &sa_size);
  751. return ConnectInternal((struct sockaddr *)&sa, sa_size);
  752. }
  753. WaitStatus SocketImpl::Connect(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port)
  754. {
  755. struct sockaddr_in6 sa = { 0 };
  756. socklen_t sa_size = 0;
  757. sockaddr_from_address(address, scope, htons(port), &sa, &sa_size);
  758. return ConnectInternal((struct sockaddr *)&sa, sa_size);
  759. }
  760. WaitStatus SocketImpl::GetLocalEndPointInfo(EndPointInfo &info)
  761. {
  762. // Note: the size here could probably be smaller
  763. uint8_t buffer[END_POINT_MAX_PATH_LEN + 3] = {0};
  764. socklen_t address_len = sizeof(buffer);
  765. SOCKET fd = (SOCKET)_fd;
  766. if (fd == -1)
  767. {
  768. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  769. return kWaitStatusFailure;
  770. }
  771. int getsocknameResult = -1;
  772. __try
  773. {
  774. getsocknameResult = getsockname(fd, (struct sockaddr *)buffer, &address_len);
  775. }
  776. __except (SocketExceptionFilter(GetExceptionCode()))
  777. {
  778. SetLastError(kWSAeshutdown);
  779. return kWaitStatusFailure;
  780. }
  781. if (getsocknameResult == -1)
  782. {
  783. StoreLastError();
  784. return kWaitStatusFailure;
  785. }
  786. if (!socketaddr_to_endpoint_info((struct sockaddr *)buffer, address_len, info))
  787. {
  788. _saved_error = kWSAeafnosupport;
  789. return kWaitStatusFailure;
  790. }
  791. return kWaitStatusSuccess;
  792. }
  793. WaitStatus SocketImpl::GetRemoteEndPointInfo(EndPointInfo &info)
  794. {
  795. // Note: the size here could probably be smaller
  796. uint8_t buffer[END_POINT_MAX_PATH_LEN + 3] = {0};
  797. socklen_t address_len = sizeof(buffer);
  798. SOCKET fd = (SOCKET)_fd;
  799. if (fd == -1)
  800. {
  801. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  802. return kWaitStatusFailure;
  803. }
  804. int getpeernameResult = -1;
  805. __try
  806. {
  807. getpeernameResult = getpeername(fd, (struct sockaddr *)buffer, &address_len);
  808. }
  809. __except (SocketExceptionFilter(GetExceptionCode()))
  810. {
  811. }
  812. if (getpeernameResult == -1)
  813. {
  814. StoreLastError();
  815. return kWaitStatusFailure;
  816. }
  817. if (!socketaddr_to_endpoint_info((struct sockaddr *)buffer, address_len, info))
  818. {
  819. _saved_error = kWSAeafnosupport;
  820. return kWaitStatusFailure;
  821. }
  822. return kWaitStatusSuccess;
  823. }
  824. WaitStatus SocketImpl::Listen(int32_t backlog)
  825. {
  826. SOCKET fd = (SOCKET)_fd;
  827. if (fd == -1)
  828. {
  829. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  830. return kWaitStatusFailure;
  831. }
  832. int listenResult = -1;
  833. __try
  834. {
  835. listenResult = listen(fd, backlog);
  836. }
  837. __except (SocketExceptionFilter(GetExceptionCode()))
  838. {
  839. }
  840. if (listenResult == -1)
  841. {
  842. StoreLastError();
  843. return kWaitStatusFailure;
  844. }
  845. return kWaitStatusSuccess;
  846. }
  847. WaitStatus SocketImpl::Shutdown(int32_t how)
  848. {
  849. SOCKET fd = (SOCKET)_fd;
  850. if (fd == -1)
  851. {
  852. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  853. return kWaitStatusFailure;
  854. }
  855. int shutdownResult = -1;
  856. __try
  857. {
  858. shutdownResult = shutdown(fd, how);
  859. }
  860. __except (SocketExceptionFilter(GetExceptionCode()))
  861. {
  862. }
  863. if (shutdownResult == -1)
  864. {
  865. StoreLastError();
  866. return kWaitStatusFailure;
  867. }
  868. if (how == SD_RECEIVE || how == SD_BOTH)
  869. _still_readable = 0;
  870. return kWaitStatusSuccess;
  871. }
  872. static SOCKET AcceptProtected(SOCKET fd)
  873. {
  874. SOCKET new_fd;
  875. do
  876. {
  877. __try
  878. {
  879. new_fd = accept(fd, NULL, 0);
  880. }
  881. __except (SocketExceptionFilter(GetExceptionCode()))
  882. {
  883. new_fd = -1;
  884. break;
  885. }
  886. }
  887. while (new_fd == -1 && errno == EINTR);
  888. return new_fd;
  889. }
  890. WaitStatus SocketImpl::Accept(os::Socket **socket)
  891. {
  892. SocketDescriptor new_fd = 0;
  893. *socket = NULL;
  894. SOCKET fd = (SOCKET)_fd;
  895. if (fd == -1)
  896. {
  897. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  898. return kWaitStatusFailure;
  899. }
  900. new_fd = AcceptProtected(fd);
  901. if (new_fd == -1)
  902. {
  903. StoreLastError();
  904. return kWaitStatusFailure;
  905. }
  906. *socket = new os::Socket(_thread_status_callback);
  907. const WaitStatus status = (*socket)->Create(new_fd, _domain, _type, _protocol);
  908. if (status != kWaitStatusSuccess)
  909. {
  910. delete *socket;
  911. *socket = NULL;
  912. return status;
  913. }
  914. return kWaitStatusSuccess;
  915. }
  916. WaitStatus SocketImpl::Disconnect(bool reuse)
  917. {
  918. GUID GuidDisconnectEx = WSAID_DISCONNECTEX;
  919. LPFN_DISCONNECTEX disconnectEx;
  920. DWORD copied;
  921. SOCKET fd = (SOCKET)_fd;
  922. if (fd == -1)
  923. {
  924. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  925. return kWaitStatusFailure;
  926. }
  927. __try
  928. {
  929. int32_t ret = WSAIoctl(fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidDisconnectEx, sizeof(GuidDisconnectEx), &disconnectEx, sizeof(disconnectEx), &copied, 0, 0);
  930. if (ret == SOCKET_ERROR)
  931. {
  932. StoreLastError();
  933. return kWaitStatusFailure;
  934. }
  935. if (!disconnectEx(fd, NULL, 0, NULL))
  936. {
  937. StoreLastError();
  938. return kWaitStatusFailure;
  939. }
  940. }
  941. __except (SocketExceptionFilter(GetExceptionCode()))
  942. {
  943. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  944. return kWaitStatusFailure;
  945. }
  946. return kWaitStatusSuccess;
  947. }
  948. WaitStatus SocketImpl::Receive(const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  949. {
  950. *len = 0;
  951. const int32_t c_flags = convert_socket_flags(flags);
  952. if (c_flags == -1)
  953. {
  954. _saved_error = kWSAeopnotsupp;
  955. return kWaitStatusFailure;
  956. }
  957. return ReceiveFromInternal(data, count, c_flags, len, NULL, 0);
  958. }
  959. WaitStatus SocketImpl::ReceiveFromInternal(const uint8_t *data, size_t count, int32_t flags, int32_t *len, struct sockaddr *from, int32_t *fromlen)
  960. {
  961. int32_t ret = 0;
  962. IL2CPP_ASSERT(count < static_cast<size_t>(std::numeric_limits<int>::max()));
  963. SOCKET fd = (SOCKET)_fd;
  964. if (fd == -1)
  965. {
  966. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  967. return kWaitStatusFailure;
  968. }
  969. do
  970. {
  971. __try
  972. {
  973. ret = recvfrom(fd, (char*)data, static_cast<int>(count), flags, from, (socklen_t*)fromlen);
  974. }
  975. __except (SocketExceptionFilter(GetExceptionCode()))
  976. {
  977. ret = -1;
  978. break;
  979. }
  980. }
  981. while (ret == -1 && errno == EINTR);
  982. if (ret == 0 && count > 0)
  983. {
  984. // According to the Linux man page, recvfrom only
  985. // returns 0 when the socket has been shut down
  986. // cleanly. Turn this into an EINTR to simulate win32
  987. // behaviour of returning EINTR when a socket is
  988. // closed while the recvfrom is blocking (we use a
  989. // shutdown() in socket_close() to trigger this.) See
  990. // bug 75705.
  991. // Distinguish between the socket being shut down at
  992. // the local or remote ends, and reads that request 0
  993. // bytes to be read
  994. // If this returns FALSE, it means the socket has been
  995. // closed locally. If it returns TRUE, but
  996. // still_readable != 1 then shutdown
  997. // (SHUT_RD|SHUT_RDWR) has been called locally.
  998. if (_still_readable != 1)
  999. {
  1000. ret = -1;
  1001. errno = EINTR;
  1002. }
  1003. }
  1004. if (ret == -1)
  1005. {
  1006. StoreLastError();
  1007. return kWaitStatusFailure;
  1008. }
  1009. *len = ret;
  1010. return kWaitStatusSuccess;
  1011. }
  1012. WaitStatus SocketImpl::Send(const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  1013. {
  1014. *len = 0;
  1015. const int32_t c_flags = convert_socket_flags(flags);
  1016. if (c_flags == -1)
  1017. {
  1018. _saved_error = kWSAeopnotsupp;
  1019. return kWaitStatusFailure;
  1020. }
  1021. SOCKET fd = (SOCKET)_fd;
  1022. if (fd == -1)
  1023. {
  1024. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1025. return kWaitStatusFailure;
  1026. }
  1027. int32_t ret = 0;
  1028. do
  1029. {
  1030. __try
  1031. {
  1032. ret = send(fd, (char*)data, count, flags);
  1033. }
  1034. __except (SocketExceptionFilter(GetExceptionCode()))
  1035. {
  1036. ret = -1;
  1037. break;
  1038. }
  1039. }
  1040. while (ret == -1 && errno == EINTR);
  1041. if (ret == -1)
  1042. {
  1043. StoreLastError();
  1044. return kWaitStatusFailure;
  1045. }
  1046. *len = ret;
  1047. return kWaitStatusSuccess;
  1048. }
  1049. WaitStatus SocketImpl::SendArray(WSABuf *wsabufs, int32_t count, int32_t *sent, SocketFlags flags)
  1050. {
  1051. DWORD c_flags = convert_socket_flags(flags);
  1052. if (c_flags == -1)
  1053. {
  1054. _saved_error = kWSAeopnotsupp;
  1055. return kWaitStatusFailure;
  1056. }
  1057. SOCKET fd = (SOCKET)_fd;
  1058. if (fd == -1)
  1059. {
  1060. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1061. return kWaitStatusFailure;
  1062. }
  1063. DWORD bytes_sent;
  1064. int32_t ret = -1;
  1065. __try
  1066. {
  1067. ret = WSASend(fd, (WSABUF*)wsabufs, count, &bytes_sent, c_flags, NULL, NULL);
  1068. }
  1069. __except (SocketExceptionFilter(GetExceptionCode()))
  1070. {
  1071. }
  1072. if (ret == SOCKET_ERROR)
  1073. {
  1074. *sent = 0;
  1075. StoreLastError();
  1076. return kWaitStatusFailure;
  1077. }
  1078. *sent = bytes_sent;
  1079. return kWaitStatusSuccess;
  1080. }
  1081. WaitStatus SocketImpl::ReceiveArray(WSABuf *wsabufs, int32_t count, int32_t *len, SocketFlags flags)
  1082. {
  1083. DWORD recv;
  1084. DWORD c_flags = convert_socket_flags(flags);
  1085. if (c_flags == -1)
  1086. {
  1087. _saved_error = kWSAeopnotsupp;
  1088. return kWaitStatusFailure;
  1089. }
  1090. SOCKET fd = (SOCKET)_fd;
  1091. if (fd == -1)
  1092. {
  1093. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1094. return kWaitStatusFailure;
  1095. }
  1096. int32_t ret = -1;
  1097. __try
  1098. {
  1099. // NOTE(gab): this cast is possible as long as WSABuf is binary compatible with WSABUF
  1100. ret = WSARecv(fd, (WSABUF*)wsabufs, count, &recv, &c_flags, NULL, NULL);
  1101. }
  1102. __except (SocketExceptionFilter(GetExceptionCode()))
  1103. {
  1104. }
  1105. if (ret == SOCKET_ERROR)
  1106. {
  1107. *len = 0;
  1108. StoreLastError();
  1109. return kWaitStatusFailure;
  1110. }
  1111. *len = recv;
  1112. return kWaitStatusSuccess;
  1113. }
  1114. WaitStatus SocketImpl::SendToInternal(struct sockaddr *sa, int32_t sa_size, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  1115. {
  1116. const int32_t c_flags = convert_socket_flags(flags);
  1117. if (c_flags == -1)
  1118. {
  1119. _saved_error = kWSAeopnotsupp;
  1120. return kWaitStatusFailure;
  1121. }
  1122. SOCKET fd = (SOCKET)_fd;
  1123. if (fd == -1)
  1124. {
  1125. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1126. return kWaitStatusFailure;
  1127. }
  1128. int32_t ret = 0;
  1129. do
  1130. {
  1131. __try
  1132. {
  1133. ret = sendto(fd, (char*)data, count, c_flags, sa, sa_size);
  1134. }
  1135. __except (SocketExceptionFilter(GetExceptionCode()))
  1136. {
  1137. ret = -1;
  1138. break;
  1139. }
  1140. }
  1141. while (ret == -1 && errno == EINTR);
  1142. if (ret == -1)
  1143. {
  1144. StoreLastError();
  1145. return kWaitStatusFailure;
  1146. }
  1147. *len = ret;
  1148. return kWaitStatusSuccess;
  1149. }
  1150. WaitStatus SocketImpl::SendTo(uint32_t address, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  1151. {
  1152. *len = 0;
  1153. struct sockaddr sa = {0};
  1154. socklen_t sa_size = 0;
  1155. sockaddr_from_address(htonl(address), htons(port), &sa, &sa_size);
  1156. return SendToInternal(&sa, sa_size, data, count, flags, len);
  1157. }
  1158. utils::Expected<WaitStatus> SocketImpl::SendTo(const char *path, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  1159. {
  1160. return utils::Il2CppError(utils::NotSupported, "Unix sockets are not supported on this platform.");
  1161. }
  1162. WaitStatus SocketImpl::SendTo(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  1163. {
  1164. *len = 0;
  1165. struct sockaddr_in6 sa = { 0 };
  1166. socklen_t sa_size = 0;
  1167. sockaddr_from_address(address, scope, htons(port), &sa, &sa_size);
  1168. return SendToInternal((sockaddr*)&sa, sa_size, data, count, flags, len);
  1169. }
  1170. WaitStatus SocketImpl::RecvFromInternal(struct sockaddr* sa, int32_t sa_size, const uint8_t* data, int32_t count, os::SocketFlags flags, int32_t* len, os::EndPointInfo& ep)
  1171. {
  1172. const int32_t c_flags = convert_socket_flags(flags);
  1173. if (c_flags == -1)
  1174. {
  1175. _saved_error = kWSAeopnotsupp;
  1176. return kWaitStatusFailure;
  1177. }
  1178. int32_t ret = 0;
  1179. const WaitStatus status = ReceiveFromInternal(data, count, c_flags, len, sa, &sa_size);
  1180. if (status != kWaitStatusSuccess)
  1181. {
  1182. ep.family = os::kAddressFamilyError;
  1183. return status;
  1184. }
  1185. if (sa_size == 0)
  1186. return kWaitStatusSuccess;
  1187. if (!socketaddr_to_endpoint_info(sa, sa_size, ep))
  1188. {
  1189. ep.family = os::kAddressFamilyError;
  1190. _saved_error = kWSAeafnosupport;
  1191. return kWaitStatusFailure;
  1192. }
  1193. return kWaitStatusSuccess;
  1194. }
  1195. WaitStatus SocketImpl::RecvFrom(uint32_t address, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep)
  1196. {
  1197. *len = 0;
  1198. struct sockaddr sa = {0};
  1199. socklen_t sa_size = 0;
  1200. sockaddr_from_address(htonl(address), htons(port), &sa, &sa_size);
  1201. return RecvFromInternal(&sa, sa_size, data, count, flags, len, ep);
  1202. }
  1203. utils::Expected<WaitStatus> SocketImpl::RecvFrom(const char *path, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep)
  1204. {
  1205. return utils::Il2CppError(utils::NotSupported, "Unix sockets are not supported on this platform.");
  1206. }
  1207. WaitStatus SocketImpl::RecvFrom(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep)
  1208. {
  1209. *len = 0;
  1210. struct sockaddr_in6 sa = { 0 };
  1211. socklen_t sa_size = 0;
  1212. sockaddr_from_address(address, scope, htons(port), &sa, &sa_size);
  1213. return RecvFromInternal((sockaddr*)&sa, sa_size, data, count, flags, len, ep);
  1214. }
  1215. WaitStatus SocketImpl::Available(int32_t *amount)
  1216. {
  1217. *amount = 0;
  1218. u_long a = 0;
  1219. SOCKET fd = (SOCKET)_fd;
  1220. if (fd == -1)
  1221. {
  1222. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1223. return kWaitStatusFailure;
  1224. }
  1225. int ioctlsocketResult = -1;
  1226. __try
  1227. {
  1228. ioctlsocketResult = ioctlsocket(fd, FIONREAD, &a);
  1229. }
  1230. __except (SocketExceptionFilter(GetExceptionCode()))
  1231. {
  1232. }
  1233. if (ioctlsocketResult == -1)
  1234. {
  1235. StoreLastError();
  1236. return kWaitStatusFailure;
  1237. }
  1238. *amount = a;
  1239. return kWaitStatusSuccess;
  1240. }
  1241. WaitStatus SocketImpl::Ioctl(int32_t command, const uint8_t *in_data, int32_t in_len, uint8_t *out_data, int32_t out_len, int32_t *written)
  1242. {
  1243. IL2CPP_ASSERT(command != 0xC8000006 /* SIO_GET_EXTENSION_FUNCTION_POINTER */ && "SIO_GET_EXTENSION_FUNCTION_POINTER ioctl command not supported");
  1244. SOCKET fd = (SOCKET)_fd;
  1245. if (fd == -1)
  1246. {
  1247. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1248. return kWaitStatusFailure;
  1249. }
  1250. DWORD len = 0;
  1251. int32_t ret = -1;
  1252. __try
  1253. {
  1254. ret = WSAIoctl(fd, command, (void*)in_data, in_len, out_data, out_len, &len, NULL, NULL);
  1255. }
  1256. __except (SocketExceptionFilter(GetExceptionCode()))
  1257. {
  1258. }
  1259. if (ret == SOCKET_ERROR)
  1260. {
  1261. StoreLastError();
  1262. return kWaitStatusFailure;
  1263. }
  1264. *written = len;
  1265. return kWaitStatusSuccess;
  1266. }
  1267. #define SKIP_OPTION -2
  1268. #define INVALID_OPTION_NAME -1
  1269. static int32_t level_and_name_to_system(SocketOptionLevel level, SocketOptionName name, int32_t *system_level, int32_t *system_name)
  1270. {
  1271. switch (level)
  1272. {
  1273. case kSocketOptionLevelSocket:
  1274. *system_level = SOL_SOCKET;
  1275. switch (name)
  1276. {
  1277. // This is SO_LINGER, because the setsockopt
  1278. // internal call maps DontLinger to SO_LINGER
  1279. // with l_onoff=0
  1280. case kSocketOptionNameDontLinger:
  1281. *system_name = SO_LINGER;
  1282. break;
  1283. case kSocketOptionNameDebug:
  1284. *system_name = SO_DEBUG;
  1285. break;
  1286. // #ifdef SO_ACCEPTCONN
  1287. case kSocketOptionNameAcceptConnection:
  1288. *system_name = SO_ACCEPTCONN;
  1289. break;
  1290. // #endif
  1291. case kSocketOptionNameReuseAddress:
  1292. *system_name = SO_REUSEADDR;
  1293. break;
  1294. case kSocketOptionNameKeepAlive:
  1295. *system_name = SO_KEEPALIVE;
  1296. break;
  1297. case kSocketOptionNameDontRoute:
  1298. *system_name = SO_DONTROUTE;
  1299. break;
  1300. case kSocketOptionNameBroadcast:
  1301. *system_name = SO_BROADCAST;
  1302. break;
  1303. case kSocketOptionNameLinger:
  1304. *system_name = SO_LINGER;
  1305. break;
  1306. case kSocketOptionNameOutOfBandInline:
  1307. *system_name = SO_OOBINLINE;
  1308. break;
  1309. case kSocketOptionNameSendBuffer:
  1310. *system_name = SO_SNDBUF;
  1311. break;
  1312. case kSocketOptionNameReceiveBuffer:
  1313. *system_name = SO_RCVBUF;
  1314. break;
  1315. case kSocketOptionNameSendLowWater:
  1316. *system_name = SO_SNDLOWAT;
  1317. break;
  1318. case kSocketOptionNameReceiveLowWater:
  1319. *system_name = SO_RCVLOWAT;
  1320. break;
  1321. case kSocketOptionNameSendTimeout:
  1322. *system_name = SO_SNDTIMEO;
  1323. break;
  1324. case kSocketOptionNameReceiveTimeout:
  1325. *system_name = SO_RCVTIMEO;
  1326. break;
  1327. case kSocketOptionNameError:
  1328. *system_name = SO_ERROR;
  1329. break;
  1330. case kSocketOptionNameType:
  1331. *system_name = SO_TYPE;
  1332. break;
  1333. case kSocketOptionNameExclusiveAddressUse:
  1334. #ifdef SO_EXCLUSIVEADDRUSE
  1335. *system_name = SO_EXCLUSIVEADDRUSE;
  1336. break;
  1337. #elif SO_REUSEADDR
  1338. *system_name = SO_REUSEADDR;
  1339. break;
  1340. #endif
  1341. case kSocketOptionNameUseLoopback:
  1342. #ifdef SO_USELOOPBACK
  1343. *system_name = SO_USELOOPBACK;
  1344. break;
  1345. #endif
  1346. case kSocketOptionNameMaxConnections:
  1347. #ifdef SO_MAXCONN
  1348. *system_name = SO_MAXCONN;
  1349. break;
  1350. #elif defined(SOMAXCONN)
  1351. *system_name = SOMAXCONN;
  1352. break;
  1353. #endif
  1354. default:
  1355. return INVALID_OPTION_NAME;
  1356. }
  1357. break;
  1358. case kSocketOptionLevelIP:
  1359. *system_level = IPPROTO_IP;
  1360. switch (name)
  1361. {
  1362. case kSocketOptionNameIPOptions:
  1363. *system_name = IP_OPTIONS;
  1364. break;
  1365. #ifdef IP_HDRINCL
  1366. case kSocketOptionNameHeaderIncluded:
  1367. *system_name = IP_HDRINCL;
  1368. break;
  1369. #endif
  1370. #ifdef IP_TOS
  1371. case kSocketOptionNameTypeOfService:
  1372. *system_name = IP_TOS;
  1373. break;
  1374. #endif
  1375. #ifdef IP_TTL
  1376. case kSocketOptionNameIpTimeToLive:
  1377. *system_name = IP_TTL;
  1378. break;
  1379. #endif
  1380. case kSocketOptionNameMulticastInterface:
  1381. *system_name = IP_MULTICAST_IF;
  1382. break;
  1383. case kSocketOptionNameMulticastTimeToLive:
  1384. *system_name = IP_MULTICAST_TTL;
  1385. break;
  1386. case kSocketOptionNameMulticastLoopback:
  1387. *system_name = IP_MULTICAST_LOOP;
  1388. break;
  1389. case kSocketOptionNameAddMembership:
  1390. *system_name = IP_ADD_MEMBERSHIP;
  1391. break;
  1392. case kSocketOptionNameDropMembership:
  1393. *system_name = IP_DROP_MEMBERSHIP;
  1394. break;
  1395. #ifdef HAVE_IP_PKTINFO
  1396. case kSocketOptionNamePacketInformation:
  1397. *system_name = IP_PKTINFO;
  1398. break;
  1399. #endif
  1400. case kSocketOptionNameDontFragment:
  1401. #ifdef IP_DONTFRAGMENT
  1402. *system_name = IP_DONTFRAGMENT;
  1403. #elif IP_MTU_DISCOVER
  1404. *system_name = IP_MTU_DISCOVER;
  1405. #elif IP_DONTFRAG
  1406. *system_name = IP_DONTFRAG;
  1407. #else
  1408. return SKIP_OPTION;
  1409. #endif
  1410. break;
  1411. case kSocketOptionNameAddSourceMembership:
  1412. case kSocketOptionNameDropSourceMembership:
  1413. case kSocketOptionNameBlockSource:
  1414. case kSocketOptionNameUnblockSource:
  1415. // Can't figure out how to map these, so fall
  1416. // through
  1417. default:
  1418. return INVALID_OPTION_NAME;
  1419. }
  1420. break;
  1421. #if IL2CPP_SUPPORT_IPV6
  1422. case kSocketOptionLevelIPv6:
  1423. *system_level = IPPROTO_IPV6;
  1424. switch (name)
  1425. {
  1426. case kSocketOptionNameMulticastInterface:
  1427. *system_name = IPV6_MULTICAST_IF;
  1428. break;
  1429. case kSocketOptionNameMulticastTimeToLive:
  1430. *system_name = IPV6_MULTICAST_HOPS;
  1431. break;
  1432. case kSocketOptionNameMulticastLoopback:
  1433. *system_name = IPV6_MULTICAST_LOOP;
  1434. break;
  1435. case kSocketOptionNameAddMembership:
  1436. *system_name = IPV6_JOIN_GROUP;
  1437. break;
  1438. case kSocketOptionNameDropMembership:
  1439. *system_name = IPV6_LEAVE_GROUP;
  1440. break;
  1441. case kSocketOptionNamePacketInformation:
  1442. #ifdef HAVE_IPV6_PKTINFO
  1443. *system_name = IPV6_PKTINFO;
  1444. break;
  1445. #endif
  1446. case kSocketOptionNameIPv6Only:
  1447. #ifdef IPV6_V6ONLY
  1448. *system_name = IPV6_V6ONLY;
  1449. break;
  1450. #endif
  1451. case kSocketOptionNameHeaderIncluded:
  1452. case kSocketOptionNameIPOptions:
  1453. case kSocketOptionNameTypeOfService:
  1454. case kSocketOptionNameDontFragment:
  1455. case kSocketOptionNameAddSourceMembership:
  1456. case kSocketOptionNameDropSourceMembership:
  1457. case kSocketOptionNameBlockSource:
  1458. case kSocketOptionNameUnblockSource:
  1459. // Can't figure out how to map these, so fall
  1460. // through
  1461. default:
  1462. return INVALID_OPTION_NAME;
  1463. }
  1464. break;
  1465. #endif // IL2CPP_SUPPORT_IPV6
  1466. case kSocketOptionLevelTcp:
  1467. #ifdef SOL_TCP
  1468. *system_level = SOL_TCP;
  1469. #else
  1470. *system_level = IPPROTO_TCP;
  1471. #endif
  1472. switch (name)
  1473. {
  1474. case kSocketOptionNameNoDelay:
  1475. *system_name = TCP_NODELAY;
  1476. break;
  1477. default:
  1478. return INVALID_OPTION_NAME;
  1479. }
  1480. break;
  1481. case kSocketOptionLevelUdp:
  1482. default:
  1483. return INVALID_OPTION_NAME;
  1484. }
  1485. return 0;
  1486. }
  1487. WaitStatus SocketImpl::GetSocketOption(SocketOptionLevel level, SocketOptionName name, uint8_t *buffer, int32_t *length)
  1488. {
  1489. int32_t system_level = 0;
  1490. int32_t system_name = 0;
  1491. const int32_t o_res = level_and_name_to_system(level, name, &system_level, &system_name);
  1492. if (o_res == SKIP_OPTION)
  1493. {
  1494. *((int32_t*)buffer) = 0;
  1495. *length = sizeof(int32_t);
  1496. return kWaitStatusSuccess;
  1497. }
  1498. if (o_res == INVALID_OPTION_NAME)
  1499. {
  1500. _saved_error = kWSAenoprotoopt;
  1501. return kWaitStatusFailure;
  1502. }
  1503. SOCKET fd = (SOCKET)_fd;
  1504. if (fd == -1)
  1505. {
  1506. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1507. return kWaitStatusFailure;
  1508. }
  1509. uint8_t *tmp_val = buffer;
  1510. int32_t ret = -1;
  1511. __try
  1512. {
  1513. ret = getsockopt(fd, system_level, system_name, (char*)tmp_val, (socklen_t*)length);
  1514. }
  1515. __except (SocketExceptionFilter(GetExceptionCode()))
  1516. {
  1517. }
  1518. if (ret == -1)
  1519. {
  1520. StoreLastError();
  1521. return kWaitStatusFailure;
  1522. }
  1523. if (system_name == SO_ERROR)
  1524. {
  1525. if (*((int32_t*)buffer) != 0)
  1526. {
  1527. StoreLastError(*((int32_t*)buffer));
  1528. }
  1529. else
  1530. {
  1531. *((int32_t*)buffer) = _saved_error;
  1532. }
  1533. }
  1534. return kWaitStatusSuccess;
  1535. }
  1536. WaitStatus SocketImpl::GetSocketOptionFull(SocketOptionLevel level, SocketOptionName name, int32_t *first, int32_t *second)
  1537. {
  1538. int32_t system_level = 0;
  1539. int32_t system_name = 0;
  1540. #if !defined(SO_EXCLUSIVEADDRUSE) && defined(SO_REUSEADDR)
  1541. if (level == kSocketOptionLevelSocket && name == kSocketOptionNameExclusiveAddressUse)
  1542. {
  1543. system_level = SOL_SOCKET;
  1544. system_name = SO_REUSEADDR;
  1545. }
  1546. else
  1547. #endif
  1548. {
  1549. const int32_t o_res = level_and_name_to_system(level, name, &system_level, &system_name);
  1550. if (o_res == SKIP_OPTION)
  1551. {
  1552. *first = 0;
  1553. *second = 0;
  1554. return kWaitStatusSuccess;
  1555. }
  1556. if (o_res == INVALID_OPTION_NAME)
  1557. {
  1558. _saved_error = kWSAenoprotoopt;
  1559. return kWaitStatusFailure;
  1560. }
  1561. }
  1562. SOCKET fd = (SOCKET)_fd;
  1563. if (fd == -1)
  1564. {
  1565. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1566. return kWaitStatusFailure;
  1567. }
  1568. int32_t ret = -1;
  1569. switch (name)
  1570. {
  1571. case kSocketOptionNameLinger:
  1572. {
  1573. struct linger linger;
  1574. socklen_t lingersize = sizeof(linger);
  1575. __try
  1576. {
  1577. ret = getsockopt(fd, system_level, system_name, (char*)&linger, &lingersize);
  1578. *first = linger.l_onoff;
  1579. *second = linger.l_linger;
  1580. }
  1581. __except (SocketExceptionFilter(GetExceptionCode()))
  1582. {
  1583. ret = -1;
  1584. }
  1585. }
  1586. break;
  1587. case kSocketOptionNameDontLinger:
  1588. {
  1589. struct linger linger;
  1590. socklen_t lingersize = sizeof(linger);
  1591. __try
  1592. {
  1593. ret = getsockopt(fd, system_level, system_name, (char*)&linger, &lingersize);
  1594. *first = !linger.l_onoff;
  1595. }
  1596. __except (SocketExceptionFilter(GetExceptionCode()))
  1597. {
  1598. ret = -1;
  1599. }
  1600. }
  1601. break;
  1602. case kSocketOptionNameSendTimeout:
  1603. case kSocketOptionNameReceiveTimeout:
  1604. {
  1605. socklen_t time_ms_size = sizeof(*first);
  1606. __try
  1607. {
  1608. ret = getsockopt(fd, system_level, system_name, (char*)first, &time_ms_size);
  1609. }
  1610. __except (SocketExceptionFilter(GetExceptionCode()))
  1611. {
  1612. ret = -1;
  1613. }
  1614. }
  1615. break;
  1616. default:
  1617. {
  1618. socklen_t valsize = sizeof(*first);
  1619. __try
  1620. {
  1621. ret = getsockopt(fd, system_level, system_name, (char*)first, &valsize);
  1622. }
  1623. __except (SocketExceptionFilter(GetExceptionCode()))
  1624. {
  1625. ret = -1;
  1626. }
  1627. }
  1628. break;
  1629. }
  1630. if (ret == -1)
  1631. {
  1632. StoreLastError();
  1633. return kWaitStatusFailure;
  1634. }
  1635. #if !defined(SO_EXCLUSIVEADDRUSE) && defined(SO_REUSEADDR)
  1636. if (level == kSocketOptionLevelSocket && name == kSocketOptionNameExclusiveAddressUse)
  1637. *first = *first ? 0 : 1;
  1638. #endif
  1639. return kWaitStatusSuccess;
  1640. }
  1641. WaitStatus SocketImpl::Poll(std::vector<PollRequest> &requests, int32_t count, int32_t timeout, int32_t *result, int32_t *error)
  1642. {
  1643. const size_t nfds = (size_t)count;
  1644. fd_set rfds, wfds, efds;
  1645. FD_ZERO(&rfds);
  1646. FD_ZERO(&wfds);
  1647. FD_ZERO(&efds);
  1648. for (size_t i = 0; i < nfds; i++)
  1649. {
  1650. SOCKET fd = static_cast<SOCKET>(requests[i].fd);
  1651. requests[i].revents = kPollFlagsNone;
  1652. if (fd == -1)
  1653. continue;
  1654. if ((requests[i].events & kPollFlagsIn) != 0)
  1655. FD_SET(fd, &rfds);
  1656. if ((requests[i].events & kPollFlagsOut) != 0)
  1657. FD_SET(fd, &wfds);
  1658. FD_SET(fd, &efds);
  1659. }
  1660. timeval timevalTimeout;
  1661. timeval* timeoutPtr = NULL;
  1662. if (timeout != -1)
  1663. {
  1664. timevalTimeout.tv_sec = timeout / 1000;
  1665. timevalTimeout.tv_usec = (timeout % 1000) * 1000;
  1666. timeoutPtr = &timevalTimeout;
  1667. }
  1668. int32_t affected = -1;
  1669. __try
  1670. {
  1671. affected = select(0, &rfds, &wfds, &efds, timeoutPtr);
  1672. }
  1673. __except (SocketExceptionFilter(GetExceptionCode()))
  1674. {
  1675. }
  1676. if (affected == -1)
  1677. {
  1678. *error = WSAGetLastError();
  1679. // Mono does this as well and the threadpool-ms-io-poll code depends on this behavior
  1680. if (*error == WSAENOTSOCK)
  1681. {
  1682. *error = os::kInvalidHandle;
  1683. }
  1684. return kWaitStatusFailure;
  1685. }
  1686. int32_t resultCount = 0;
  1687. for (size_t i = 0; i < nfds && affected > 0; i++)
  1688. {
  1689. SOCKET fd = static_cast<SOCKET>(requests[i].fd);
  1690. if (fd == -1)
  1691. continue;
  1692. if ((requests[i].events & kPollFlagsIn) != 0 && FD_ISSET(fd, &rfds))
  1693. {
  1694. requests[i].revents |= kPollFlagsIn;
  1695. affected--;
  1696. }
  1697. if ((requests[i].events & kPollFlagsOut) != 0 && FD_ISSET(fd, &wfds))
  1698. {
  1699. requests[i].revents |= kPollFlagsOut;
  1700. affected--;
  1701. }
  1702. if (FD_ISSET(fd, &efds))
  1703. {
  1704. requests[i].revents |= kPollFlagsErr;
  1705. affected--;
  1706. }
  1707. if (requests[i].revents != kPollFlagsNone)
  1708. resultCount++;
  1709. }
  1710. *result = resultCount;
  1711. return kWaitStatusSuccess;
  1712. }
  1713. WaitStatus SocketImpl::Poll(std::vector<PollRequest>& requests, int32_t timeout, int32_t *result, int32_t *error)
  1714. {
  1715. return Poll(requests, (int32_t)requests.size(), timeout, result, error);
  1716. }
  1717. WaitStatus SocketImpl::Poll(PollRequest& request, int32_t timeout, int32_t *result, int32_t *error)
  1718. {
  1719. std::vector<PollRequest> requests;
  1720. requests.push_back(request);
  1721. return Poll(requests, 1, timeout, result, error);
  1722. }
  1723. WaitStatus SocketImpl::SetSocketOption(SocketOptionLevel level, SocketOptionName name, int32_t value)
  1724. {
  1725. int32_t system_level = 0;
  1726. int32_t system_name = 0;
  1727. const int32_t o_res = level_and_name_to_system(level, name, &system_level, &system_name);
  1728. if (o_res == SKIP_OPTION)
  1729. {
  1730. return kWaitStatusSuccess;
  1731. }
  1732. if (o_res == INVALID_OPTION_NAME)
  1733. {
  1734. _saved_error = kWSAenoprotoopt;
  1735. return kWaitStatusFailure;
  1736. }
  1737. struct linger linger;
  1738. WaitStatus ret = kWaitStatusFailure;
  1739. switch (name)
  1740. {
  1741. case kSocketOptionNameDontLinger:
  1742. linger.l_onoff = !value;
  1743. linger.l_linger = 0;
  1744. ret = SetSocketOptionInternal(system_level, system_name, &linger, sizeof(linger));
  1745. break;
  1746. case kSocketOptionNameDontFragment:
  1747. #ifdef IP_PMTUDISC_DO
  1748. // Fiddle with the value slightly if we're turning DF on
  1749. if (value == 1)
  1750. value = IP_PMTUDISC_DO;
  1751. #endif
  1752. ret = SetSocketOptionInternal(system_level, system_name, (char*)&value, sizeof(value));
  1753. break;
  1754. default:
  1755. ret = SetSocketOptionInternal(system_level, system_name, (char*)&value, sizeof(value));
  1756. break;
  1757. }
  1758. return ret;
  1759. }
  1760. WaitStatus SocketImpl::SetSocketOptionLinger(SocketOptionLevel level, SocketOptionName name, bool enabled, int32_t seconds)
  1761. {
  1762. int32_t system_level = 0;
  1763. int32_t system_name = 0;
  1764. const int32_t o_res = level_and_name_to_system(level, name, &system_level, &system_name);
  1765. if (o_res == SKIP_OPTION)
  1766. {
  1767. return kWaitStatusSuccess;
  1768. }
  1769. if (o_res == INVALID_OPTION_NAME)
  1770. {
  1771. _saved_error = kWSAenoprotoopt;
  1772. return kWaitStatusFailure;
  1773. }
  1774. struct linger linger;
  1775. linger.l_onoff = enabled;
  1776. linger.l_linger = seconds;
  1777. return SetSocketOptionInternal(system_level, system_name, &linger, sizeof(linger));
  1778. }
  1779. WaitStatus SocketImpl::SetSocketOptionArray(SocketOptionLevel level, SocketOptionName name, const uint8_t *buffer, int32_t length)
  1780. {
  1781. int32_t system_level = 0;
  1782. int32_t system_name = 0;
  1783. const int32_t o_res = level_and_name_to_system(level, name, &system_level, &system_name);
  1784. if (o_res == SKIP_OPTION)
  1785. {
  1786. return kWaitStatusSuccess;
  1787. }
  1788. if (o_res == INVALID_OPTION_NAME)
  1789. {
  1790. _saved_error = kWSAenoprotoopt;
  1791. return kWaitStatusFailure;
  1792. }
  1793. struct linger linger;
  1794. WaitStatus ret = kWaitStatusFailure;
  1795. switch (name)
  1796. {
  1797. case kSocketOptionNameDontLinger:
  1798. if (length == 1)
  1799. {
  1800. linger.l_linger = 0;
  1801. linger.l_onoff = (*((char*)buffer)) ? 0 : 1;
  1802. ret = SetSocketOptionInternal(system_level, system_name, &linger, sizeof(linger));
  1803. }
  1804. else
  1805. {
  1806. _saved_error = kWSAeinval;
  1807. return kWaitStatusFailure;
  1808. }
  1809. break;
  1810. default:
  1811. ret = SetSocketOptionInternal(system_level, system_name, buffer, length);
  1812. break;
  1813. }
  1814. return ret;
  1815. }
  1816. WaitStatus SocketImpl::SetSocketOptionMembership(SocketOptionLevel level, SocketOptionName name, uint32_t group_address, uint32_t local_address)
  1817. {
  1818. int32_t system_level = 0;
  1819. int32_t system_name = 0;
  1820. const int32_t o_res = level_and_name_to_system(level, name, &system_level, &system_name);
  1821. if (o_res == SKIP_OPTION)
  1822. {
  1823. return kWaitStatusSuccess;
  1824. }
  1825. if (o_res == INVALID_OPTION_NAME)
  1826. {
  1827. _saved_error = kWSAenoprotoopt;
  1828. return kWaitStatusFailure;
  1829. }
  1830. IP_MREQ mreq = {{0}};
  1831. mreq.imr_multiaddr.s_addr = group_address;
  1832. mreq.imr_interface.s_addr = local_address;
  1833. return SetSocketOptionInternal(system_level, system_name, &mreq, sizeof(mreq));
  1834. return kWaitStatusFailure;
  1835. }
  1836. #if IL2CPP_SUPPORT_IPV6
  1837. WaitStatus SocketImpl::SetSocketOptionMembership(SocketOptionLevel level, SocketOptionName name, IPv6Address ipv6, uint64_t interfaceOffset)
  1838. {
  1839. int32_t system_level = 0;
  1840. int32_t system_name = 0;
  1841. const int32_t o_res = level_and_name_to_system(level, name, &system_level, &system_name);
  1842. if (o_res == SKIP_OPTION)
  1843. {
  1844. return kWaitStatusSuccess;
  1845. }
  1846. if (o_res == INVALID_OPTION_NAME)
  1847. {
  1848. _saved_error = kWSAenoprotoopt;
  1849. return kWaitStatusFailure;
  1850. }
  1851. struct ipv6_mreq mreq6 = { { 0 } };
  1852. struct in6_addr in6addr;
  1853. for (int i = 0; i < 16; ++i)
  1854. in6addr.s6_addr[i] = ipv6.addr[i];
  1855. mreq6.ipv6mr_multiaddr = in6addr;
  1856. mreq6.ipv6mr_interface = (ULONG)interfaceOffset;
  1857. return SetSocketOptionInternal(system_level, system_name, &mreq6, sizeof(mreq6));
  1858. }
  1859. #endif
  1860. WaitStatus SocketImpl::SetSocketOptionInternal(int32_t level, int32_t name, const void *value, int32_t len)
  1861. {
  1862. const void *real_val = value;
  1863. SOCKET fd = (SOCKET)_fd;
  1864. if (fd == -1)
  1865. {
  1866. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1867. return kWaitStatusFailure;
  1868. }
  1869. int32_t ret = -1;
  1870. __try
  1871. {
  1872. ret = setsockopt(fd, level, name, (const char*)real_val, (socklen_t)len);
  1873. }
  1874. __except (SocketExceptionFilter(GetExceptionCode()))
  1875. {
  1876. }
  1877. if (ret == -1)
  1878. {
  1879. StoreLastError();
  1880. return kWaitStatusFailure;
  1881. }
  1882. return kWaitStatusSuccess;
  1883. }
  1884. int32_t WSAIoctlProtected(SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
  1885. {
  1886. __try
  1887. {
  1888. return WSAIoctl(s, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpOverlapped, lpCompletionRoutine);
  1889. }
  1890. __except (SocketExceptionFilter(GetExceptionCode()))
  1891. {
  1892. }
  1893. return -1;
  1894. }
  1895. BOOL transmitFileProtected(LPFN_TRANSMITFILE transmitFile, SOCKET hSocket, HANDLE hFile, DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, LPOVERLAPPED lpOverlapped, LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD dwReserved)
  1896. {
  1897. __try
  1898. {
  1899. return transmitFile(hSocket, hFile, nNumberOfBytesToWrite, nNumberOfBytesPerSend, lpOverlapped, lpTransmitBuffers, dwReserved);
  1900. }
  1901. __except (SocketExceptionFilter(GetExceptionCode()))
  1902. {
  1903. }
  1904. return FALSE;
  1905. }
  1906. WaitStatus SocketImpl::SendFile(const char *filename, TransmitFileBuffers *buffers, TransmitFileOptions options)
  1907. {
  1908. if (filename == NULL)
  1909. return kWaitStatusFailure;
  1910. const UTF16String wideFilename = utils::StringUtils::Utf8ToUtf16(filename);
  1911. HANDLE file = CreateFileW((LPCWSTR)wideFilename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  1912. if (file == INVALID_HANDLE_VALUE)
  1913. {
  1914. StoreLastError();
  1915. return kWaitStatusFailure;
  1916. }
  1917. GUID transmitFileGuid = WSAID_TRANSMITFILE;
  1918. LPFN_TRANSMITFILE transmitFile;
  1919. DWORD copied;
  1920. SOCKET fd = (SOCKET)_fd;
  1921. if (fd == -1)
  1922. {
  1923. Error::SetLastError(il2cpp::os::kWSAeshutdown);
  1924. return kWaitStatusFailure;
  1925. }
  1926. int32_t ret = WSAIoctlProtected(fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &transmitFileGuid, sizeof(transmitFileGuid), &transmitFile, sizeof(transmitFile), &copied, 0, 0);
  1927. if (ret == SOCKET_ERROR)
  1928. {
  1929. StoreLastError();
  1930. return kWaitStatusFailure;
  1931. }
  1932. if (!transmitFileProtected(transmitFile, fd, file, 0, 0, NULL, (TRANSMIT_FILE_BUFFERS*)buffers, options))
  1933. {
  1934. StoreLastError();
  1935. CloseHandle(file);
  1936. return kWaitStatusFailure;
  1937. }
  1938. CloseHandle(file);
  1939. return kWaitStatusSuccess;
  1940. }
  1941. }
  1942. }
  1943. #endif