sock_bsd.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. /*
  2. * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  3. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include <pj/sock.h>
  20. #include <pj/os.h>
  21. #include <pj/assert.h>
  22. #include <pj/string.h>
  23. #include <pj/compat/socket.h>
  24. #include <pj/addr_resolv.h>
  25. #include <pj/errno.h>
  26. #include <pj/unicode.h>
  27. #if 0
  28. /* Enable some tracing */
  29. #include <pj/log.h>
  30. #define TRACE_(arg) PJ_LOG(4,arg)
  31. #else
  32. #define TRACE_(arg)
  33. #endif
  34. #define THIS_FILE "sock_bsd.c"
  35. /*
  36. * Address families conversion.
  37. * The values here are indexed based on pj_addr_family.
  38. */
  39. const pj_uint16_t PJ_AF_UNSPEC = AF_UNSPEC;
  40. const pj_uint16_t PJ_AF_UNIX = AF_UNIX;
  41. const pj_uint16_t PJ_AF_INET = AF_INET;
  42. const pj_uint16_t PJ_AF_INET6 = AF_INET6;
  43. #ifdef AF_PACKET
  44. const pj_uint16_t PJ_AF_PACKET = AF_PACKET;
  45. #else
  46. const pj_uint16_t PJ_AF_PACKET = 0xFFFF;
  47. #endif
  48. #ifdef AF_IRDA
  49. const pj_uint16_t PJ_AF_IRDA = AF_IRDA;
  50. #else
  51. const pj_uint16_t PJ_AF_IRDA = 0xFFFF;
  52. #endif
  53. /*
  54. * Socket types conversion.
  55. * The values here are indexed based on pj_sock_type
  56. */
  57. const pj_uint16_t PJ_SOCK_STREAM= SOCK_STREAM;
  58. const pj_uint16_t PJ_SOCK_DGRAM = SOCK_DGRAM;
  59. const pj_uint16_t PJ_SOCK_RAW = SOCK_RAW;
  60. const pj_uint16_t PJ_SOCK_RDM = SOCK_RDM;
  61. #if defined(SOCK_CLOEXEC)
  62. const int PJ_SOCK_CLOEXEC = SOCK_CLOEXEC;
  63. #elif defined(PJ_WIN32) || defined(PJ_WIN64)
  64. const int PJ_SOCK_CLOEXEC = 0;
  65. #else
  66. /*
  67. * On some unix-like platforms (eg. macos), SOCK_CLOEXEC is not defined,
  68. * It can use #pj_set_cloexec_flag() to set socket close-on-exec flag.
  69. *
  70. * Set PJ_SOCK_CLOEXEC to a non-zero value,
  71. * together with the macro SOCK_CLOEXEC to determine whether it should
  72. * set socket close-on-exec flag.
  73. * #if !defined(SOCK_CLOEXEC)
  74. * if (type & pj_SOCK_CLOEXEC() == pj_SOCK_CLOEXEC()) {
  75. * // set close-on-exec flag
  76. * }
  77. * #endif
  78. */
  79. const int PJ_SOCK_CLOEXEC = 02000000;
  80. #endif
  81. /*
  82. * Socket level values.
  83. */
  84. const pj_uint16_t PJ_SOL_SOCKET = SOL_SOCKET;
  85. #if (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64) || \
  86. (defined (IPPROTO_IP))
  87. const pj_uint16_t PJ_SOL_IP = IPPROTO_IP;
  88. #elif defined(SOL_IP)
  89. const pj_uint16_t PJ_SOL_IP = SOL_IP;
  90. #else
  91. const pj_uint16_t PJ_SOL_IP = 0;
  92. #endif /* SOL_IP */
  93. #if defined(SOL_TCP)
  94. const pj_uint16_t PJ_SOL_TCP = SOL_TCP;
  95. #elif defined(IPPROTO_TCP)
  96. const pj_uint16_t PJ_SOL_TCP = IPPROTO_TCP;
  97. #elif (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64)
  98. const pj_uint16_t PJ_SOL_TCP = IPPROTO_TCP;
  99. #else
  100. const pj_uint16_t PJ_SOL_TCP = 6;
  101. #endif /* SOL_TCP */
  102. #ifdef SOL_UDP
  103. const pj_uint16_t PJ_SOL_UDP = SOL_UDP;
  104. #elif defined(IPPROTO_UDP)
  105. const pj_uint16_t PJ_SOL_UDP = IPPROTO_UDP;
  106. #elif (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64)
  107. const pj_uint16_t PJ_SOL_UDP = IPPROTO_UDP;
  108. #else
  109. const pj_uint16_t PJ_SOL_UDP = 17;
  110. #endif /* SOL_UDP */
  111. #ifdef SOL_IPV6
  112. const pj_uint16_t PJ_SOL_IPV6 = SOL_IPV6;
  113. #elif (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_WIN64) && PJ_WIN64)
  114. # if defined(IPPROTO_IPV6) || (_WIN32_WINNT >= 0x0501)
  115. const pj_uint16_t PJ_SOL_IPV6 = IPPROTO_IPV6;
  116. # else
  117. const pj_uint16_t PJ_SOL_IPV6 = 41;
  118. # endif
  119. #else
  120. const pj_uint16_t PJ_SOL_IPV6 = 41;
  121. #endif /* SOL_IPV6 */
  122. /* IP_TOS */
  123. #ifdef IP_TOS
  124. const pj_uint16_t PJ_IP_TOS = IP_TOS;
  125. #else
  126. const pj_uint16_t PJ_IP_TOS = 1;
  127. #endif
  128. /* TOS settings (declared in netinet/ip.h) */
  129. #ifdef IPTOS_LOWDELAY
  130. const pj_uint16_t PJ_IPTOS_LOWDELAY = IPTOS_LOWDELAY;
  131. #else
  132. const pj_uint16_t PJ_IPTOS_LOWDELAY = 0x10;
  133. #endif
  134. #ifdef IPTOS_THROUGHPUT
  135. const pj_uint16_t PJ_IPTOS_THROUGHPUT = IPTOS_THROUGHPUT;
  136. #else
  137. const pj_uint16_t PJ_IPTOS_THROUGHPUT = 0x08;
  138. #endif
  139. #ifdef IPTOS_RELIABILITY
  140. const pj_uint16_t PJ_IPTOS_RELIABILITY = IPTOS_RELIABILITY;
  141. #else
  142. const pj_uint16_t PJ_IPTOS_RELIABILITY = 0x04;
  143. #endif
  144. #ifdef IPTOS_MINCOST
  145. const pj_uint16_t PJ_IPTOS_MINCOST = IPTOS_MINCOST;
  146. #else
  147. const pj_uint16_t PJ_IPTOS_MINCOST = 0x02;
  148. #endif
  149. /* IPV6_TCLASS */
  150. #ifdef IPV6_TCLASS
  151. const pj_uint16_t PJ_IPV6_TCLASS = IPV6_TCLASS;
  152. #else
  153. const pj_uint16_t PJ_IPV6_TCLASS = 0xFFFF;
  154. #endif
  155. /* optname values. */
  156. const pj_uint16_t PJ_SO_TYPE = SO_TYPE;
  157. const pj_uint16_t PJ_SO_RCVBUF = SO_RCVBUF;
  158. const pj_uint16_t PJ_SO_SNDBUF = SO_SNDBUF;
  159. const pj_uint16_t PJ_TCP_NODELAY= TCP_NODELAY;
  160. const pj_uint16_t PJ_SO_REUSEADDR= SO_REUSEADDR;
  161. #ifdef SO_NOSIGPIPE
  162. const pj_uint16_t PJ_SO_NOSIGPIPE = SO_NOSIGPIPE;
  163. #else
  164. const pj_uint16_t PJ_SO_NOSIGPIPE = 0xFFFF;
  165. #endif
  166. #if defined(SO_PRIORITY)
  167. const pj_uint16_t PJ_SO_PRIORITY = SO_PRIORITY;
  168. #else
  169. /* This is from Linux, YMMV */
  170. const pj_uint16_t PJ_SO_PRIORITY = 12;
  171. #endif
  172. /* Multicasting is not supported e.g. in PocketPC 2003 SDK */
  173. #ifdef IP_MULTICAST_IF
  174. const pj_uint16_t PJ_IP_MULTICAST_IF = IP_MULTICAST_IF;
  175. const pj_uint16_t PJ_IP_MULTICAST_TTL = IP_MULTICAST_TTL;
  176. const pj_uint16_t PJ_IP_MULTICAST_LOOP = IP_MULTICAST_LOOP;
  177. const pj_uint16_t PJ_IP_ADD_MEMBERSHIP = IP_ADD_MEMBERSHIP;
  178. const pj_uint16_t PJ_IP_DROP_MEMBERSHIP = IP_DROP_MEMBERSHIP;
  179. #else
  180. const pj_uint16_t PJ_IP_MULTICAST_IF = 0xFFFF;
  181. const pj_uint16_t PJ_IP_MULTICAST_TTL = 0xFFFF;
  182. const pj_uint16_t PJ_IP_MULTICAST_LOOP = 0xFFFF;
  183. const pj_uint16_t PJ_IP_ADD_MEMBERSHIP = 0xFFFF;
  184. const pj_uint16_t PJ_IP_DROP_MEMBERSHIP = 0xFFFF;
  185. #endif
  186. /* recv() and send() flags */
  187. const int PJ_MSG_OOB = MSG_OOB;
  188. const int PJ_MSG_PEEK = MSG_PEEK;
  189. const int PJ_MSG_DONTROUTE = MSG_DONTROUTE;
  190. #if 0
  191. static void CHECK_ADDR_LEN(const pj_sockaddr *addr, int len)
  192. {
  193. pj_sockaddr *a = (pj_sockaddr*)addr;
  194. pj_assert((a->addr.sa_family==PJ_AF_INET && len==sizeof(pj_sockaddr_in)) ||
  195. (a->addr.sa_family==PJ_AF_INET6 && len==sizeof(pj_sockaddr_in6)));
  196. }
  197. #else
  198. #define CHECK_ADDR_LEN(addr,len)
  199. #endif
  200. /*
  201. * Convert 16-bit value from network byte order to host byte order.
  202. */
  203. PJ_DEF(pj_uint16_t) pj_ntohs(pj_uint16_t netshort)
  204. {
  205. return ntohs(netshort);
  206. }
  207. /*
  208. * Convert 16-bit value from host byte order to network byte order.
  209. */
  210. PJ_DEF(pj_uint16_t) pj_htons(pj_uint16_t hostshort)
  211. {
  212. return htons(hostshort);
  213. }
  214. /*
  215. * Convert 32-bit value from network byte order to host byte order.
  216. */
  217. PJ_DEF(pj_uint32_t) pj_ntohl(pj_uint32_t netlong)
  218. {
  219. return ntohl(netlong);
  220. }
  221. /*
  222. * Convert 32-bit value from host byte order to network byte order.
  223. */
  224. PJ_DEF(pj_uint32_t) pj_htonl(pj_uint32_t hostlong)
  225. {
  226. return htonl(hostlong);
  227. }
  228. /*
  229. * Convert an Internet host address given in network byte order
  230. * to string in standard numbers and dots notation.
  231. */
  232. PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
  233. {
  234. #if 0
  235. return inet_ntoa(*(struct in_addr*)&inaddr);
  236. #else
  237. struct in_addr addr;
  238. //addr.s_addr = inaddr.s_addr;
  239. pj_memcpy(&addr, &inaddr, sizeof(addr));
  240. return inet_ntoa(addr);
  241. #endif
  242. }
  243. /*
  244. * This function converts the Internet host address cp from the standard
  245. * numbers-and-dots notation into binary data and stores it in the structure
  246. * that inp points to.
  247. */
  248. PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)
  249. {
  250. char tempaddr[PJ_INET_ADDRSTRLEN];
  251. /* Initialize output with PJ_INADDR_NONE.
  252. * Some apps relies on this instead of the return value
  253. * (and anyway the return value is quite confusing!)
  254. */
  255. inp->s_addr = PJ_INADDR_NONE;
  256. /* Caution:
  257. * this function might be called with cp->slen >= 16
  258. * (i.e. when called with hostname to check if it's an IP addr).
  259. */
  260. PJ_ASSERT_RETURN(cp && cp->slen && inp, 0);
  261. if (cp->slen >= PJ_INET_ADDRSTRLEN) {
  262. return 0;
  263. }
  264. pj_memcpy(tempaddr, cp->ptr, cp->slen);
  265. tempaddr[cp->slen] = '\0';
  266. #if defined(PJ_SOCK_HAS_INET_ATON) && PJ_SOCK_HAS_INET_ATON != 0
  267. return inet_aton(tempaddr, (struct in_addr*)inp);
  268. #else
  269. inp->s_addr = inet_addr(tempaddr);
  270. return inp->s_addr == PJ_INADDR_NONE ? 0 : 1;
  271. #endif
  272. }
  273. /*
  274. * Convert text to IPv4/IPv6 address.
  275. */
  276. PJ_DEF(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst)
  277. {
  278. char tempaddr[PJ_INET6_ADDRSTRLEN];
  279. PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP);
  280. PJ_ASSERT_RETURN(src && src->slen && dst, PJ_EINVAL);
  281. /* Initialize output with PJ_IN_ADDR_NONE for IPv4 (to be
  282. * compatible with pj_inet_aton()
  283. */
  284. if (af==PJ_AF_INET) {
  285. ((pj_in_addr*)dst)->s_addr = PJ_INADDR_NONE;
  286. }
  287. /* Caution:
  288. * this function might be called with cp->slen >= 46
  289. * (i.e. when called with hostname to check if it's an IP addr).
  290. */
  291. if (src->slen >= PJ_INET6_ADDRSTRLEN) {
  292. return PJ_ENAMETOOLONG;
  293. }
  294. pj_memcpy(tempaddr, src->ptr, src->slen);
  295. tempaddr[src->slen] = '\0';
  296. #if defined(PJ_SOCK_HAS_INET_PTON) && PJ_SOCK_HAS_INET_PTON != 0
  297. /*
  298. * Implementation using inet_pton()
  299. */
  300. if (inet_pton(af, tempaddr, dst) != 1) {
  301. pj_status_t status = pj_get_netos_error();
  302. if (status == PJ_SUCCESS)
  303. status = PJ_EUNKNOWN;
  304. return status;
  305. }
  306. return PJ_SUCCESS;
  307. #elif defined(PJ_WIN32) || defined(PJ_WIN64) || defined(PJ_WIN32_WINCE)
  308. /*
  309. * Implementation on Windows, using WSAStringToAddress().
  310. * Should also work on Unicode systems.
  311. */
  312. {
  313. PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN)
  314. pj_sockaddr sock_addr;
  315. int addr_len = sizeof(sock_addr);
  316. int rc;
  317. sock_addr.addr.sa_family = (pj_uint16_t)af;
  318. rc = WSAStringToAddress(
  319. PJ_STRING_TO_NATIVE(tempaddr,wtempaddr,sizeof(wtempaddr)),
  320. af, NULL, (LPSOCKADDR)&sock_addr, &addr_len);
  321. if (rc != 0) {
  322. /* If you get rc 130022 Invalid argument (WSAEINVAL) with IPv6,
  323. * check that you have IPv6 enabled (install it in the network
  324. * adapter).
  325. */
  326. pj_status_t status = pj_get_netos_error();
  327. if (status == PJ_SUCCESS)
  328. status = PJ_EUNKNOWN;
  329. return status;
  330. }
  331. if (sock_addr.addr.sa_family == PJ_AF_INET) {
  332. pj_memcpy(dst, &sock_addr.ipv4.sin_addr, 4);
  333. return PJ_SUCCESS;
  334. } else if (sock_addr.addr.sa_family == PJ_AF_INET6) {
  335. pj_memcpy(dst, &sock_addr.ipv6.sin6_addr, 16);
  336. return PJ_SUCCESS;
  337. } else {
  338. pj_assert(!"Shouldn't happen");
  339. return PJ_EBUG;
  340. }
  341. }
  342. #elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0
  343. /* IPv6 support is disabled, just return error without raising assertion */
  344. return PJ_EIPV6NOTSUP;
  345. #else
  346. pj_assert(!"Not supported");
  347. return PJ_EIPV6NOTSUP;
  348. #endif
  349. }
  350. /*
  351. * Convert IPv4/IPv6 address to text.
  352. */
  353. PJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src,
  354. char *dst, int size)
  355. {
  356. PJ_ASSERT_RETURN(src && dst && size, PJ_EINVAL);
  357. *dst = '\0';
  358. PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP);
  359. #if defined(PJ_SOCK_HAS_INET_NTOP) && PJ_SOCK_HAS_INET_NTOP != 0
  360. /*
  361. * Implementation using inet_ntop()
  362. */
  363. if (inet_ntop(af, src, dst, size) == NULL) {
  364. pj_status_t status = pj_get_netos_error();
  365. if (status == PJ_SUCCESS)
  366. status = PJ_EUNKNOWN;
  367. return status;
  368. }
  369. return PJ_SUCCESS;
  370. #elif defined(PJ_WIN32) || defined(PJ_WIN64) || defined(PJ_WIN32_WINCE)
  371. /*
  372. * Implementation on Windows, using WSAAddressToString().
  373. * Should also work on Unicode systems.
  374. */
  375. {
  376. PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN)
  377. pj_sockaddr sock_addr;
  378. DWORD addr_len, addr_str_len;
  379. int rc;
  380. pj_bzero(&sock_addr, sizeof(sock_addr));
  381. sock_addr.addr.sa_family = (pj_uint16_t)af;
  382. if (af == PJ_AF_INET) {
  383. if (size < PJ_INET_ADDRSTRLEN)
  384. return PJ_ETOOSMALL;
  385. pj_memcpy(&sock_addr.ipv4.sin_addr, src, 4);
  386. addr_len = sizeof(pj_sockaddr_in);
  387. addr_str_len = PJ_INET_ADDRSTRLEN;
  388. } else if (af == PJ_AF_INET6) {
  389. if (size < PJ_INET6_ADDRSTRLEN)
  390. return PJ_ETOOSMALL;
  391. pj_memcpy(&sock_addr.ipv6.sin6_addr, src, 16);
  392. addr_len = sizeof(pj_sockaddr_in6);
  393. addr_str_len = PJ_INET6_ADDRSTRLEN;
  394. } else {
  395. pj_assert(!"Unsupported address family");
  396. return PJ_EAFNOTSUP;
  397. }
  398. #if PJ_NATIVE_STRING_IS_UNICODE
  399. rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len,
  400. NULL, wtempaddr, &addr_str_len);
  401. if (rc == 0) {
  402. pj_unicode_to_ansi(wtempaddr, wcslen(wtempaddr), dst, size);
  403. }
  404. #else
  405. rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len,
  406. NULL, dst, &addr_str_len);
  407. #endif
  408. if (rc != 0) {
  409. pj_status_t status = pj_get_netos_error();
  410. if (status == PJ_SUCCESS)
  411. status = PJ_EUNKNOWN;
  412. return status;
  413. }
  414. return PJ_SUCCESS;
  415. }
  416. #elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0
  417. /* IPv6 support is disabled, just return error without raising assertion */
  418. return PJ_EIPV6NOTSUP;
  419. #else
  420. pj_assert(!"Not supported");
  421. return PJ_EIPV6NOTSUP;
  422. #endif
  423. }
  424. /*
  425. * Get hostname.
  426. */
  427. PJ_DEF(const pj_str_t*) pj_gethostname(void)
  428. {
  429. static char buf[PJ_MAX_HOSTNAME];
  430. static pj_str_t hostname;
  431. PJ_CHECK_STACK();
  432. if (hostname.ptr == NULL) {
  433. hostname.ptr = buf;
  434. if (gethostname(buf, sizeof(buf)) != 0) {
  435. hostname.ptr[0] = '\0';
  436. hostname.slen = 0;
  437. } else {
  438. hostname.slen = strlen(buf);
  439. }
  440. }
  441. return &hostname;
  442. }
  443. #if defined(PJ_WIN32) || defined(PJ_WIN64)
  444. /*
  445. * Create new socket/endpoint for communication and returns a descriptor.
  446. */
  447. PJ_DEF(pj_status_t) pj_sock_socket(int af,
  448. int type,
  449. int proto,
  450. pj_sock_t *sock)
  451. {
  452. PJ_CHECK_STACK();
  453. /* Sanity checks. */
  454. PJ_ASSERT_RETURN(sock!=NULL, PJ_EINVAL);
  455. PJ_ASSERT_RETURN((SOCKET)PJ_INVALID_SOCKET==INVALID_SOCKET,
  456. (*sock=PJ_INVALID_SOCKET, PJ_EINVAL));
  457. *sock = WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED);
  458. if (*sock == PJ_INVALID_SOCKET)
  459. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  460. #if PJ_SOCK_DISABLE_WSAECONNRESET && \
  461. (!defined(PJ_WIN32_WINCE) || PJ_WIN32_WINCE==0)
  462. #ifndef SIO_UDP_CONNRESET
  463. #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
  464. #endif
  465. /* Disable WSAECONNRESET for UDP.
  466. * See https://github.com/pjsip/pjproject/issues/1197
  467. */
  468. if (type==PJ_SOCK_DGRAM) {
  469. DWORD dwBytesReturned = 0;
  470. BOOL bNewBehavior = FALSE;
  471. DWORD rc;
  472. rc = WSAIoctl(*sock, SIO_UDP_CONNRESET,
  473. &bNewBehavior, sizeof(bNewBehavior),
  474. NULL, 0, &dwBytesReturned,
  475. NULL, NULL);
  476. if (rc==SOCKET_ERROR) {
  477. // Ignored..
  478. }
  479. }
  480. #endif
  481. return PJ_SUCCESS;
  482. }
  483. #else
  484. /*
  485. * Create new socket/endpoint for communication and returns a descriptor.
  486. */
  487. PJ_DEF(pj_status_t) pj_sock_socket(int af,
  488. int type,
  489. int proto,
  490. pj_sock_t *sock)
  491. {
  492. int type0 = type;
  493. PJ_CHECK_STACK();
  494. /* Sanity checks. */
  495. PJ_ASSERT_RETURN(sock!=NULL, PJ_EINVAL);
  496. PJ_ASSERT_RETURN(PJ_INVALID_SOCKET==-1,
  497. (*sock=PJ_INVALID_SOCKET, PJ_EINVAL));
  498. #if !defined(SOCK_CLOEXEC)
  499. if ((type0 & pj_SOCK_CLOEXEC()) == pj_SOCK_CLOEXEC())
  500. type &= ~pj_SOCK_CLOEXEC();
  501. #else
  502. PJ_UNUSED_ARG(type0);
  503. #endif
  504. *sock = socket(af, type, proto);
  505. TRACE_((THIS_FILE, "Created new socket of type %d: %ld", type, *sock));
  506. if (*sock == PJ_INVALID_SOCKET)
  507. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  508. else {
  509. pj_int32_t val = 1;
  510. if ((type & 0xF) == pj_SOCK_STREAM()) {
  511. pj_sock_setsockopt(*sock, pj_SOL_SOCKET(), pj_SO_NOSIGPIPE(),
  512. &val, sizeof(val));
  513. }
  514. #if defined(PJ_SOCK_HAS_IPV6_V6ONLY) && PJ_SOCK_HAS_IPV6_V6ONLY != 0
  515. if (af == PJ_AF_INET6) {
  516. pj_sock_setsockopt(*sock, PJ_SOL_IPV6, IPV6_V6ONLY,
  517. &val, sizeof(val));
  518. }
  519. #endif
  520. #if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
  521. PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
  522. if ((type & 0xF) == pj_SOCK_DGRAM()) {
  523. pj_sock_setsockopt(*sock, pj_SOL_SOCKET(), SO_NOSIGPIPE,
  524. &val, sizeof(val));
  525. }
  526. #endif
  527. #if !defined(SOCK_CLOEXEC)
  528. if ((type0 & pj_SOCK_CLOEXEC()) == pj_SOCK_CLOEXEC())
  529. pj_set_cloexec_flag((int)(*sock));
  530. #endif
  531. return PJ_SUCCESS;
  532. }
  533. }
  534. #endif
  535. /*
  536. * Bind socket.
  537. */
  538. PJ_DEF(pj_status_t) pj_sock_bind( pj_sock_t sock,
  539. const pj_sockaddr_t *addr,
  540. int len)
  541. {
  542. PJ_CHECK_STACK();
  543. PJ_ASSERT_RETURN(addr && len >= (int)sizeof(struct sockaddr_in), PJ_EINVAL);
  544. CHECK_ADDR_LEN(addr, len);
  545. if (bind(sock, (struct sockaddr*)addr, len) != 0)
  546. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  547. else
  548. return PJ_SUCCESS;
  549. }
  550. /*
  551. * Bind socket.
  552. */
  553. PJ_DEF(pj_status_t) pj_sock_bind_in( pj_sock_t sock,
  554. pj_uint32_t addr32,
  555. pj_uint16_t port)
  556. {
  557. pj_sockaddr_in addr;
  558. PJ_CHECK_STACK();
  559. PJ_SOCKADDR_SET_LEN(&addr, sizeof(pj_sockaddr_in));
  560. addr.sin_family = PJ_AF_INET;
  561. pj_bzero(addr.sin_zero_pad, sizeof(addr.sin_zero_pad));
  562. addr.sin_addr.s_addr = pj_htonl(addr32);
  563. addr.sin_port = pj_htons(port);
  564. return pj_sock_bind(sock, &addr, sizeof(pj_sockaddr_in));
  565. }
  566. /*
  567. * Close socket.
  568. */
  569. PJ_DEF(pj_status_t) pj_sock_close(pj_sock_t sock)
  570. {
  571. int rc;
  572. PJ_CHECK_STACK();
  573. #if defined(PJ_WIN32) && PJ_WIN32!=0 || \
  574. defined(PJ_WIN64) && PJ_WIN64 != 0 || \
  575. defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
  576. rc = closesocket(sock);
  577. #else
  578. rc = close(sock);
  579. #endif
  580. if (rc != 0)
  581. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  582. else
  583. return PJ_SUCCESS;
  584. }
  585. /*
  586. * Get remote's name.
  587. */
  588. PJ_DEF(pj_status_t) pj_sock_getpeername( pj_sock_t sock,
  589. pj_sockaddr_t *addr,
  590. int *namelen)
  591. {
  592. PJ_CHECK_STACK();
  593. if (getpeername(sock, (struct sockaddr*)addr, (socklen_t*)namelen) != 0)
  594. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  595. else {
  596. PJ_SOCKADDR_RESET_LEN(addr);
  597. return PJ_SUCCESS;
  598. }
  599. }
  600. /*
  601. * Get socket name.
  602. */
  603. PJ_DEF(pj_status_t) pj_sock_getsockname( pj_sock_t sock,
  604. pj_sockaddr_t *addr,
  605. int *namelen)
  606. {
  607. PJ_CHECK_STACK();
  608. if (getsockname(sock, (struct sockaddr*)addr, (socklen_t*)namelen) != 0)
  609. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  610. else {
  611. PJ_SOCKADDR_RESET_LEN(addr);
  612. return PJ_SUCCESS;
  613. }
  614. }
  615. /*
  616. * Send data
  617. */
  618. PJ_DEF(pj_status_t) pj_sock_send(pj_sock_t sock,
  619. const void *buf,
  620. pj_ssize_t *len,
  621. unsigned flags)
  622. {
  623. PJ_CHECK_STACK();
  624. PJ_ASSERT_RETURN(len, PJ_EINVAL);
  625. #ifdef MSG_NOSIGNAL
  626. /* Suppress SIGPIPE. See https://github.com/pjsip/pjproject/issues/1538 */
  627. flags |= MSG_NOSIGNAL;
  628. #endif
  629. *len = send(sock, (const char*)buf, (int)(*len), flags);
  630. if (*len < 0)
  631. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  632. else
  633. return PJ_SUCCESS;
  634. }
  635. /*
  636. * Send data.
  637. */
  638. PJ_DEF(pj_status_t) pj_sock_sendto(pj_sock_t sock,
  639. const void *buf,
  640. pj_ssize_t *len,
  641. unsigned flags,
  642. const pj_sockaddr_t *to,
  643. int tolen)
  644. {
  645. PJ_CHECK_STACK();
  646. PJ_ASSERT_RETURN(len, PJ_EINVAL);
  647. CHECK_ADDR_LEN(to, tolen);
  648. #ifdef MSG_NOSIGNAL
  649. /* Suppress SIGPIPE. See https://github.com/pjsip/pjproject/issues/1538 */
  650. flags |= MSG_NOSIGNAL;
  651. #endif
  652. *len = sendto(sock, (const char*)buf, (int)(*len), flags,
  653. (const struct sockaddr*)to, tolen);
  654. if (*len < 0)
  655. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  656. else
  657. return PJ_SUCCESS;
  658. }
  659. /*
  660. * Receive data.
  661. */
  662. PJ_DEF(pj_status_t) pj_sock_recv(pj_sock_t sock,
  663. void *buf,
  664. pj_ssize_t *len,
  665. unsigned flags)
  666. {
  667. PJ_CHECK_STACK();
  668. PJ_ASSERT_RETURN(buf && len, PJ_EINVAL);
  669. *len = recv(sock, (char*)buf, (int)(*len), flags);
  670. if (*len < 0)
  671. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  672. else
  673. return PJ_SUCCESS;
  674. }
  675. /*
  676. * Receive data.
  677. */
  678. PJ_DEF(pj_status_t) pj_sock_recvfrom(pj_sock_t sock,
  679. void *buf,
  680. pj_ssize_t *len,
  681. unsigned flags,
  682. pj_sockaddr_t *from,
  683. int *fromlen)
  684. {
  685. PJ_CHECK_STACK();
  686. PJ_ASSERT_RETURN(buf && len, PJ_EINVAL);
  687. *len = recvfrom(sock, (char*)buf, (int)(*len), flags,
  688. (struct sockaddr*)from, (socklen_t*)fromlen);
  689. if (*len < 0)
  690. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  691. else {
  692. if (from) {
  693. PJ_SOCKADDR_RESET_LEN(from);
  694. }
  695. return PJ_SUCCESS;
  696. }
  697. }
  698. /*
  699. * Get socket option.
  700. */
  701. PJ_DEF(pj_status_t) pj_sock_getsockopt( pj_sock_t sock,
  702. pj_uint16_t level,
  703. pj_uint16_t optname,
  704. void *optval,
  705. int *optlen)
  706. {
  707. PJ_CHECK_STACK();
  708. PJ_ASSERT_RETURN(optval && optlen, PJ_EINVAL);
  709. if (getsockopt(sock, level, optname, (char*)optval, (socklen_t*)optlen)!=0)
  710. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  711. else
  712. return PJ_SUCCESS;
  713. }
  714. /*
  715. * Set socket option.
  716. */
  717. PJ_DEF(pj_status_t) pj_sock_setsockopt( pj_sock_t sock,
  718. pj_uint16_t level,
  719. pj_uint16_t optname,
  720. const void *optval,
  721. int optlen)
  722. {
  723. int status;
  724. PJ_CHECK_STACK();
  725. #if (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_SUNOS) && PJ_SUNOS)
  726. /* Some opt may still need int value (e.g:SO_EXCLUSIVEADDRUSE in win32). */
  727. status = setsockopt(sock,
  728. level,
  729. ((optname&0xff00)==0xff00)?(int)optname|0xffff0000:optname,
  730. (const char*)optval, optlen);
  731. #else
  732. status = setsockopt(sock, level, optname, (const char*)optval, optlen);
  733. TRACE_((THIS_FILE, "setsockopt %ld level:%d name:%d val:%d(%d)->%d", sock,
  734. level, optname, *((const char *)optval), optlen, status));
  735. #endif
  736. if (status != 0)
  737. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  738. else
  739. return PJ_SUCCESS;
  740. }
  741. /*
  742. * Set socket option.
  743. */
  744. PJ_DEF(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd,
  745. const pj_sockopt_params *params)
  746. {
  747. unsigned int i = 0;
  748. pj_status_t retval = PJ_SUCCESS;
  749. PJ_CHECK_STACK();
  750. PJ_ASSERT_RETURN(params, PJ_EINVAL);
  751. for (;i<params->cnt && i<PJ_MAX_SOCKOPT_PARAMS;++i) {
  752. pj_status_t status = pj_sock_setsockopt(sockfd,
  753. (pj_uint16_t)params->options[i].level,
  754. (pj_uint16_t)params->options[i].optname,
  755. params->options[i].optval,
  756. params->options[i].optlen);
  757. if (status != PJ_SUCCESS) {
  758. retval = status;
  759. PJ_PERROR(4,(THIS_FILE, status,
  760. "Warning: error applying sock opt %d",
  761. params->options[i].optname));
  762. }
  763. }
  764. return retval;
  765. }
  766. /*
  767. * Connect socket.
  768. */
  769. PJ_DEF(pj_status_t) pj_sock_connect( pj_sock_t sock,
  770. const pj_sockaddr_t *addr,
  771. int namelen)
  772. {
  773. PJ_CHECK_STACK();
  774. if (connect(sock, (struct sockaddr*)addr, namelen) != 0)
  775. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  776. else
  777. return PJ_SUCCESS;
  778. }
  779. /*
  780. * Shutdown socket.
  781. */
  782. #if PJ_HAS_TCP
  783. PJ_DEF(pj_status_t) pj_sock_shutdown( pj_sock_t sock,
  784. int how)
  785. {
  786. PJ_CHECK_STACK();
  787. if (shutdown(sock, how) != 0)
  788. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  789. else
  790. return PJ_SUCCESS;
  791. }
  792. /*
  793. * Start listening to incoming connections.
  794. */
  795. PJ_DEF(pj_status_t) pj_sock_listen( pj_sock_t sock,
  796. int backlog)
  797. {
  798. PJ_CHECK_STACK();
  799. if (listen(sock, backlog) != 0)
  800. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  801. else
  802. return PJ_SUCCESS;
  803. }
  804. /*
  805. * Accept incoming connections
  806. */
  807. PJ_DEF(pj_status_t) pj_sock_accept( pj_sock_t serverfd,
  808. pj_sock_t *newsock,
  809. pj_sockaddr_t *addr,
  810. int *addrlen)
  811. {
  812. PJ_CHECK_STACK();
  813. PJ_ASSERT_RETURN(newsock != NULL, PJ_EINVAL);
  814. #if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
  815. if (addr) {
  816. PJ_SOCKADDR_SET_LEN(addr, *addrlen);
  817. }
  818. #endif
  819. *newsock = accept(serverfd, (struct sockaddr*)addr, (socklen_t*)addrlen);
  820. if (*newsock==PJ_INVALID_SOCKET)
  821. return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
  822. else {
  823. #if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
  824. if (addr) {
  825. PJ_SOCKADDR_RESET_LEN(addr);
  826. }
  827. #endif
  828. return PJ_SUCCESS;
  829. }
  830. }
  831. #endif /* PJ_HAS_TCP */