PageRenderTime 27ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/idjc-0.8.7/libshout/src/net/sock.c

#
C | 893 lines | 637 code | 133 blank | 123 comment | 132 complexity | 166a4bf8313681e1024aef99fc34f5c7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0
  1. /* -*- c-basic-offset: 4; -*- */
  2. /* sock.c: General Socket Functions
  3. *
  4. * Copyright (c) 1999 the icecast team
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Library General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Library General Public
  17. * License along with this library; if not, write to the Free
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #ifdef HAVE_CONFIG_H
  21. #include <config.h>
  22. #endif
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <stdarg.h>
  26. #include <sys/types.h>
  27. #include <ctype.h>
  28. #include <string.h>
  29. #include <fcntl.h>
  30. #include <errno.h>
  31. #ifdef HAVE_POLL
  32. #include <poll.h>
  33. #endif
  34. #ifdef HAVE_SYS_SELECT_H
  35. #include <sys/select.h>
  36. #endif
  37. #ifndef _WIN32
  38. #include <unistd.h>
  39. #include <sys/socket.h>
  40. #include <netinet/in.h>
  41. #include <netinet/tcp.h>
  42. #include <arpa/inet.h>
  43. #include <sys/time.h>
  44. #include <netdb.h>
  45. #else
  46. #include <winsock2.h>
  47. #define vsnprintf _vsnprintf
  48. #define EINPROGRESS WSAEINPROGRESS
  49. #define ENOTSOCK WSAENOTSOCK
  50. #define EWOULDBLOCK WSAEWOULDBLOCK
  51. #define EALREADY WSAEALREADY
  52. #define socklen_t int
  53. #ifndef __MINGW32__
  54. #define va_copy(ap1, ap2) memcpy(&ap1, &ap2, sizeof(va_list))
  55. #endif
  56. #endif
  57. #include "sock.h"
  58. #include "resolver.h"
  59. /* for older C libraries */
  60. #ifndef AI_NUMERICSERV
  61. # define AI_NUMERICSERV 0
  62. #endif
  63. #ifndef AI_ADDRCONFIG
  64. # define AI_ADDRCONFIG 0
  65. #endif
  66. /* sock_initialize
  67. **
  68. ** initializes the socket library. you must call this
  69. ** before using the library!
  70. */
  71. void sock_initialize(void)
  72. {
  73. #ifdef _WIN32
  74. WSADATA wsad;
  75. WSAStartup(0x0101, &wsad);
  76. #endif
  77. resolver_initialize();
  78. }
  79. /* sock_shutdown
  80. **
  81. ** shutdown the socket library. remember to call this when you're
  82. ** through using the lib
  83. */
  84. void sock_shutdown(void)
  85. {
  86. #ifdef _WIN32
  87. WSACleanup();
  88. #endif
  89. resolver_shutdown();
  90. }
  91. /* sock_get_localip
  92. **
  93. ** gets the local ip address for the machine
  94. ** the ip it returns *should* be on the internet.
  95. ** in any case, it's as close as we can hope to get
  96. ** unless someone has better ideas on how to do this
  97. */
  98. char *sock_get_localip(char *buff, int len)
  99. {
  100. char temp[1024];
  101. if (gethostname(temp, sizeof(temp)) != 0)
  102. return NULL;
  103. if (resolver_getip(temp, buff, len))
  104. return buff;
  105. return NULL;
  106. }
  107. /* sock_error
  108. **
  109. ** returns the last socket error
  110. */
  111. int sock_error(void)
  112. {
  113. #ifdef _WIN32
  114. return WSAGetLastError();
  115. #else
  116. return errno;
  117. #endif
  118. }
  119. static void sock_set_error(int val)
  120. {
  121. #ifdef _WIN32
  122. WSASetLastError (val);
  123. #else
  124. errno = val;
  125. #endif
  126. }
  127. /* sock_recoverable
  128. **
  129. ** determines if the socket error is recoverable
  130. ** in terms of non blocking sockets
  131. */
  132. int sock_recoverable(int error)
  133. {
  134. switch (error)
  135. {
  136. case 0:
  137. case EAGAIN:
  138. case EINTR:
  139. case EINPROGRESS:
  140. #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
  141. case EWOULDBLOCK:
  142. #endif
  143. #ifdef ERESTART
  144. case ERESTART:
  145. #endif
  146. return 1;
  147. default:
  148. return 0;
  149. }
  150. }
  151. int sock_stalled (int error)
  152. {
  153. switch (error)
  154. {
  155. case EAGAIN:
  156. case EINPROGRESS:
  157. case EALREADY:
  158. #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
  159. case EWOULDBLOCK:
  160. #endif
  161. #ifdef ERESTART
  162. case ERESTART:
  163. #endif
  164. return 1;
  165. default:
  166. return 0;
  167. }
  168. }
  169. static int sock_connect_pending (int error)
  170. {
  171. return error == EINPROGRESS || error == EALREADY;
  172. }
  173. /* sock_valid_socket
  174. **
  175. ** determines if a sock_t represents a valid socket
  176. */
  177. int sock_valid_socket(sock_t sock)
  178. {
  179. int ret;
  180. int optval;
  181. socklen_t optlen;
  182. optlen = sizeof(int);
  183. /* apparently on windows getsockopt.optval is a char * */
  184. ret = getsockopt(sock, SOL_SOCKET, SO_TYPE, (void*) &optval, &optlen);
  185. return (ret == 0);
  186. }
  187. /* determines if the passed socket is still connected */
  188. int sock_active (sock_t sock)
  189. {
  190. char c;
  191. int l;
  192. l = recv (sock, &c, 1, MSG_PEEK);
  193. if (l == 0)
  194. return 0;
  195. if (l < 0 && sock_recoverable (sock_error()))
  196. return 1;
  197. return 0;
  198. }
  199. /* inet_aton
  200. **
  201. ** turns an ascii ip address into a binary representation
  202. */
  203. #ifdef _WIN32
  204. int inet_aton(const char *s, struct in_addr *a)
  205. {
  206. int lsb, b2, b3, msb;
  207. if (sscanf(s, "%d.%d.%d.%d", &lsb, &b2, &b3, &msb) < 4) {
  208. return 0;
  209. }
  210. a->s_addr = inet_addr(s);
  211. return (a->s_addr != INADDR_NONE);
  212. }
  213. #endif /* _WIN32 */
  214. int sock_set_blocking(sock_t sock, const int block)
  215. {
  216. #ifdef _WIN32
  217. #ifdef __MINGW32__
  218. u_long varblock = block;
  219. #else
  220. int varblock = block;
  221. #endif
  222. #endif
  223. if ((!sock_valid_socket(sock)) || (block < 0) || (block > 1))
  224. return SOCK_ERROR;
  225. #ifdef _WIN32
  226. return ioctlsocket(sock, FIONBIO, &varblock);
  227. #else
  228. return fcntl(sock, F_SETFL, (block) ? 0 : O_NONBLOCK);
  229. #endif
  230. }
  231. int sock_set_nolinger(sock_t sock)
  232. {
  233. struct linger lin = { 0, 0 };
  234. return setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&lin,
  235. sizeof(struct linger));
  236. }
  237. int sock_set_nodelay(sock_t sock)
  238. {
  239. int nodelay = 1;
  240. return setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&nodelay,
  241. sizeof(int));
  242. }
  243. int sock_set_keepalive(sock_t sock)
  244. {
  245. int keepalive = 1;
  246. return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive,
  247. sizeof(int));
  248. }
  249. /* sock_close
  250. **
  251. ** close the socket
  252. */
  253. int sock_close(sock_t sock)
  254. {
  255. #ifdef _WIN32
  256. return closesocket(sock);
  257. #else
  258. return close(sock);
  259. #endif
  260. }
  261. /* sock_writev
  262. *
  263. * write multiple buffers at once, return bytes actually written
  264. */
  265. #ifdef HAVE_WRITEV
  266. ssize_t sock_writev (sock_t sock, const struct iovec *iov, size_t count)
  267. {
  268. return writev (sock, iov, count);
  269. }
  270. #else
  271. ssize_t sock_writev (sock_t sock, const struct iovec *iov, size_t count)
  272. {
  273. int i = count, accum = 0, ret;
  274. const struct iovec *v = iov;
  275. while (i)
  276. {
  277. if (v->iov_base && v->iov_len)
  278. {
  279. ret = sock_write_bytes (sock, v->iov_base, v->iov_len);
  280. if (ret == -1 && accum==0)
  281. return -1;
  282. if (ret == -1)
  283. ret = 0;
  284. accum += ret;
  285. if (ret < (int)v->iov_len)
  286. break;
  287. }
  288. v++;
  289. i--;
  290. }
  291. return accum;
  292. }
  293. #endif
  294. /* sock_write_bytes
  295. **
  296. ** write bytes to the socket
  297. ** this function will _NOT_ block
  298. */
  299. int sock_write_bytes(sock_t sock, const void *buff, size_t len)
  300. {
  301. /* sanity check */
  302. if (!buff) {
  303. return SOCK_ERROR;
  304. } else if (len <= 0) {
  305. return SOCK_ERROR;
  306. } /*else if (!sock_valid_socket(sock)) {
  307. return SOCK_ERROR;
  308. } */
  309. return send(sock, buff, len, 0);
  310. }
  311. /* sock_write_string
  312. **
  313. ** writes a string to a socket
  314. ** This function must only be called with a blocking socket.
  315. */
  316. int sock_write_string(sock_t sock, const char *buff)
  317. {
  318. return (sock_write_bytes(sock, buff, strlen(buff)) > 0);
  319. }
  320. /* sock_write
  321. **
  322. ** write a formatted string to the socket
  323. ** this function must only be called with a blocking socket.
  324. ** will truncate the string if it's greater than 1024 chars.
  325. */
  326. int sock_write(sock_t sock, const char *fmt, ...)
  327. {
  328. int rc;
  329. va_list ap;
  330. va_start (ap, fmt);
  331. rc = sock_write_fmt (sock, fmt, ap);
  332. va_end (ap);
  333. return rc;
  334. }
  335. #ifdef HAVE_OLD_VSNPRINTF
  336. int sock_write_fmt(sock_t sock, const char *fmt, va_list ap)
  337. {
  338. va_list ap_local;
  339. unsigned int len = 1024;
  340. char *buff = NULL;
  341. int ret;
  342. /* don't go infinite, but stop at some huge limit */
  343. while (len < 2*1024*1024)
  344. {
  345. char *tmp = realloc (buff, len);
  346. ret = -1;
  347. if (tmp == NULL)
  348. break;
  349. buff = tmp;
  350. va_copy (ap_local, ap);
  351. ret = vsnprintf (buff, len, fmt, ap_local);
  352. if (ret > 0)
  353. {
  354. ret = sock_write_bytes (sock, buff, ret);
  355. break;
  356. }
  357. len += 8192;
  358. }
  359. free (buff);
  360. return ret;
  361. }
  362. #else
  363. int sock_write_fmt(sock_t sock, const char *fmt, va_list ap)
  364. {
  365. char buffer [1024], *buff = buffer;
  366. int len;
  367. int rc = SOCK_ERROR;
  368. va_list ap_retry;
  369. va_copy (ap_retry, ap);
  370. len = vsnprintf (buff, sizeof (buffer), fmt, ap);
  371. if (len > 0)
  372. {
  373. if ((size_t)len < sizeof (buffer)) /* common case */
  374. rc = sock_write_bytes(sock, buff, (size_t)len);
  375. else
  376. {
  377. /* truncated */
  378. buff = malloc (++len);
  379. if (buff)
  380. {
  381. len = vsnprintf (buff, len, fmt, ap_retry);
  382. if (len > 0)
  383. rc = sock_write_bytes (sock, buff, len);
  384. free (buff);
  385. }
  386. }
  387. }
  388. va_end (ap_retry);
  389. return rc;
  390. }
  391. #endif
  392. int sock_read_bytes(sock_t sock, char *buff, size_t len)
  393. {
  394. /*if (!sock_valid_socket(sock)) return 0; */
  395. if (!buff) return 0;
  396. if (len <= 0) return 0;
  397. return recv(sock, buff, len, 0);
  398. }
  399. /* sock_read_line
  400. **
  401. ** Read one line of at max len bytes from sock into buff.
  402. ** If ok, return 1 and nullterminate buff. Otherwize return 0.
  403. ** Terminating \n is not put into the buffer.
  404. **
  405. ** this function will probably not work on sockets in nonblocking mode
  406. */
  407. int sock_read_line(sock_t sock, char *buff, const int len)
  408. {
  409. char c = '\0';
  410. int read_bytes, pos;
  411. /*if (!sock_valid_socket(sock)) {
  412. return 0;
  413. } else*/ if (!buff) {
  414. return 0;
  415. } else if (len <= 0) {
  416. return 0;
  417. }
  418. pos = 0;
  419. read_bytes = recv(sock, &c, 1, 0);
  420. if (read_bytes < 0) {
  421. return 0;
  422. }
  423. while ((c != '\n') && (pos < len) && (read_bytes == 1)) {
  424. if (c != '\r')
  425. buff[pos++] = c;
  426. read_bytes = recv(sock, &c, 1, 0);
  427. }
  428. if (read_bytes == 1) {
  429. buff[pos] = '\0';
  430. return 1;
  431. } else {
  432. return 0;
  433. }
  434. }
  435. /* see if a connection has been established. If timeout is < 0 then wait
  436. * indefinitely, else wait for the stated number of seconds.
  437. * return SOCK_TIMEOUT for timeout
  438. * return SOCK_ERROR for failure
  439. * return 0 for try again, interrupted
  440. * return 1 for ok
  441. */
  442. #ifdef HAVE_POLL
  443. int sock_connected (sock_t sock, int timeout)
  444. {
  445. struct pollfd check;
  446. check.fd = sock;
  447. check.events = POLLOUT;
  448. switch (poll (&check, 1, timeout*1000))
  449. {
  450. case 0: return SOCK_TIMEOUT;
  451. case -1:
  452. if (sock_recoverable (sock_error()))
  453. return 0;
  454. return SOCK_ERROR;
  455. default: return 1;
  456. }
  457. }
  458. #else
  459. int sock_connected (sock_t sock, int timeout)
  460. {
  461. fd_set wfds;
  462. int val = SOCK_ERROR;
  463. socklen_t size = sizeof val;
  464. struct timeval tv, *timeval = NULL;
  465. /* make a timeout of <0 be indefinite */
  466. if (timeout >= 0)
  467. {
  468. tv.tv_sec = timeout;
  469. tv.tv_usec = 0;
  470. timeval = &tv;
  471. }
  472. FD_ZERO(&wfds);
  473. FD_SET(sock, &wfds);
  474. switch (select(sock + 1, NULL, &wfds, NULL, timeval))
  475. {
  476. case 0:
  477. return SOCK_TIMEOUT;
  478. default:
  479. /* on windows getsockopt.val is defined as char* */
  480. if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) &val, &size) == 0)
  481. {
  482. if (val == 0)
  483. return 1;
  484. sock_set_error (val);
  485. }
  486. /* fall through */
  487. case -1:
  488. if (sock_recoverable (sock_error()))
  489. return 0;
  490. return SOCK_ERROR;
  491. }
  492. }
  493. #endif
  494. #ifdef HAVE_GETADDRINFO
  495. sock_t sock_connect_non_blocking (const char *hostname, unsigned port)
  496. {
  497. int sock = SOCK_ERROR;
  498. struct addrinfo *ai, *head, hints;
  499. char service[8];
  500. memset (&hints, 0, sizeof (hints));
  501. hints.ai_family = AF_UNSPEC;
  502. hints.ai_socktype = SOCK_STREAM;
  503. snprintf (service, sizeof (service), "%u", port);
  504. if (getaddrinfo (hostname, service, &hints, &head))
  505. return SOCK_ERROR;
  506. ai = head;
  507. while (ai)
  508. {
  509. if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol))
  510. > -1)
  511. {
  512. sock_set_blocking (sock, 0);
  513. if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 &&
  514. !sock_connect_pending(sock_error()))
  515. {
  516. sock_close (sock);
  517. sock = SOCK_ERROR;
  518. }
  519. else
  520. break;
  521. }
  522. ai = ai->ai_next;
  523. }
  524. if (head) freeaddrinfo (head);
  525. return sock;
  526. }
  527. /* issue a connect, but return after the timeout (seconds) is reached. If
  528. * timeout is 0 or less then we will wait until the OS gives up on the connect
  529. * The socket is returned
  530. */
  531. sock_t sock_connect_wto(const char *hostname, int port, int timeout)
  532. {
  533. sock_t sock = SOCK_ERROR;
  534. struct addrinfo *ai, *head, hints;
  535. char service[8];
  536. memset (&hints, 0, sizeof (hints));
  537. hints.ai_family = AF_UNSPEC;
  538. hints.ai_socktype = SOCK_STREAM;
  539. snprintf (service, sizeof (service), "%u", port);
  540. if (getaddrinfo (hostname, service, &hints, &head))
  541. return SOCK_ERROR;
  542. ai = head;
  543. while (ai)
  544. {
  545. if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) >= 0)
  546. {
  547. if (timeout > 0)
  548. sock_set_blocking (sock, 0);
  549. if (connect (sock, ai->ai_addr, ai->ai_addrlen) == 0)
  550. break;
  551. /* loop as the connect maybe async */
  552. while (sock != SOCK_ERROR)
  553. {
  554. if (sock_recoverable (sock_error()))
  555. {
  556. int connected = sock_connected (sock, timeout);
  557. if (connected == 0) /* try again, interrupted */
  558. continue;
  559. if (connected == 1) /* connected */
  560. {
  561. if (timeout >= 0)
  562. sock_set_blocking(sock, 1);
  563. break;
  564. }
  565. }
  566. sock_close (sock);
  567. sock = SOCK_ERROR;
  568. }
  569. if (sock != SOCK_ERROR)
  570. break;
  571. }
  572. ai = ai->ai_next;
  573. }
  574. if (head)
  575. freeaddrinfo (head);
  576. return sock;
  577. }
  578. sock_t sock_get_server_socket (int port, const char *sinterface)
  579. {
  580. struct sockaddr_storage sa;
  581. struct addrinfo hints, *res, *ai;
  582. char service [10];
  583. int sock;
  584. if (port < 0)
  585. return SOCK_ERROR;
  586. memset (&sa, 0, sizeof(sa));
  587. memset (&hints, 0, sizeof(hints));
  588. hints.ai_family = AF_UNSPEC;
  589. hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG | AI_NUMERICSERV | AI_NUMERICHOST;
  590. hints.ai_socktype = SOCK_STREAM;
  591. snprintf (service, sizeof (service), "%d", port);
  592. if (getaddrinfo (sinterface, service, &hints, &res))
  593. return SOCK_ERROR;
  594. ai = res;
  595. do
  596. {
  597. int on = 1;
  598. sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  599. if (sock < 0)
  600. continue;
  601. setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on));
  602. on = 0;
  603. #ifdef IPV6_V6ONLY
  604. setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof on);
  605. #endif
  606. if (bind (sock, ai->ai_addr, ai->ai_addrlen) < 0)
  607. {
  608. sock_close (sock);
  609. continue;
  610. }
  611. freeaddrinfo (res);
  612. return sock;
  613. } while ((ai = ai->ai_next));
  614. freeaddrinfo (res);
  615. return SOCK_ERROR;
  616. }
  617. #else
  618. int sock_try_connection (sock_t sock, const char *hostname, unsigned int port)
  619. {
  620. struct sockaddr_in sin, server;
  621. char ip[MAX_ADDR_LEN];
  622. if (!hostname || !hostname[0] || port == 0)
  623. return -1;
  624. memset(&sin, 0, sizeof(struct sockaddr_in));
  625. memset(&server, 0, sizeof(struct sockaddr_in));
  626. if (!resolver_getip(hostname, ip, MAX_ADDR_LEN))
  627. {
  628. sock_close (sock);
  629. return -1;
  630. }
  631. if (inet_aton(ip, (struct in_addr *)&sin.sin_addr) == 0)
  632. {
  633. sock_close(sock);
  634. return -1;
  635. }
  636. memcpy(&server.sin_addr, &sin.sin_addr, sizeof(struct sockaddr_in));
  637. server.sin_family = AF_INET;
  638. server.sin_port = htons(port);
  639. return connect(sock, (struct sockaddr *)&server, sizeof(server));
  640. }
  641. sock_t sock_connect_non_blocking (const char *hostname, unsigned port)
  642. {
  643. sock_t sock;
  644. sock = socket(AF_INET, SOCK_STREAM, 0);
  645. if (sock == SOCK_ERROR)
  646. return SOCK_ERROR;
  647. sock_set_blocking (sock, 0);
  648. sock_try_connection (sock, hostname, port);
  649. return sock;
  650. }
  651. sock_t sock_connect_wto(const char *hostname, int port, int timeout)
  652. {
  653. sock_t sock;
  654. sock = socket(AF_INET, SOCK_STREAM, 0);
  655. if (sock == SOCK_ERROR)
  656. return SOCK_ERROR;
  657. if (timeout)
  658. {
  659. sock_set_blocking (sock, 0);
  660. if (sock_try_connection (sock, hostname, port) < 0)
  661. {
  662. int ret = sock_connected (sock, timeout);
  663. if (ret <= 0)
  664. {
  665. sock_close (sock);
  666. return SOCK_ERROR;
  667. }
  668. }
  669. sock_set_blocking(sock, 1);
  670. }
  671. else
  672. {
  673. if (sock_try_connection (sock, hostname, port) < 0)
  674. {
  675. sock_close (sock);
  676. sock = SOCK_ERROR;
  677. }
  678. }
  679. return sock;
  680. }
  681. /* sock_get_server_socket
  682. **
  683. ** create a socket for incoming requests on a specified port and
  684. ** interface. if interface is null, listen on all interfaces.
  685. ** returns the socket, or SOCK_ERROR on failure
  686. */
  687. sock_t sock_get_server_socket(int port, const char *sinterface)
  688. {
  689. struct sockaddr_in sa;
  690. int error, opt;
  691. sock_t sock;
  692. char ip[MAX_ADDR_LEN];
  693. if (port < 0)
  694. return SOCK_ERROR;
  695. /* defaults */
  696. memset(&sa, 0, sizeof(sa));
  697. /* set the interface to bind to if specified */
  698. if (sinterface != NULL) {
  699. if (!resolver_getip(sinterface, ip, sizeof (ip)))
  700. return SOCK_ERROR;
  701. if (!inet_aton(ip, &sa.sin_addr)) {
  702. return SOCK_ERROR;
  703. } else {
  704. sa.sin_family = AF_INET;
  705. sa.sin_port = htons(port);
  706. }
  707. } else {
  708. sa.sin_addr.s_addr = INADDR_ANY;
  709. sa.sin_family = AF_INET;
  710. sa.sin_port = htons(port);
  711. }
  712. /* get a socket */
  713. sock = socket (AF_INET, SOCK_STREAM, 0);
  714. if (sock == -1)
  715. return SOCK_ERROR;
  716. /* reuse it if we can */
  717. opt = 1;
  718. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(int));
  719. /* bind socket to port */
  720. error = bind(sock, (struct sockaddr *)&sa, sizeof (struct sockaddr_in));
  721. if (error == -1)
  722. return SOCK_ERROR;
  723. return sock;
  724. }
  725. #endif
  726. int sock_listen(sock_t serversock, int backlog)
  727. {
  728. if (!sock_valid_socket(serversock))
  729. return 0;
  730. if (backlog <= 0)
  731. backlog = 10;
  732. return (listen(serversock, backlog) == 0);
  733. }
  734. sock_t sock_accept(sock_t serversock, char *ip, size_t len)
  735. {
  736. #ifdef HAVE_GETNAMEINFO
  737. struct sockaddr_storage sa;
  738. #else
  739. struct sockaddr_in sa;
  740. #endif
  741. sock_t ret;
  742. socklen_t slen;
  743. if (ip == NULL || len == 0 || !sock_valid_socket(serversock))
  744. return SOCK_ERROR;
  745. slen = sizeof(sa);
  746. ret = accept(serversock, (struct sockaddr *)&sa, &slen);
  747. if (ret != SOCK_ERROR)
  748. {
  749. #ifdef HAVE_GETNAMEINFO
  750. if (getnameinfo ((struct sockaddr *)&sa, slen, ip, len, NULL, 0, NI_NUMERICHOST))
  751. snprintf (ip, len, "unknown");
  752. #else
  753. /* inet_ntoa is not reentrant, we should protect this */
  754. strncpy(ip, inet_ntoa(sa.sin_addr), len);
  755. #endif
  756. sock_set_nolinger(ret);
  757. sock_set_keepalive(ret);
  758. }
  759. return ret;
  760. }