2
0

sockets.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "apr_arch_networkio.h"
  17. #include "apr_network_io.h"
  18. #include "apr_general.h"
  19. #include "apr_lib.h"
  20. #include "apr_portable.h"
  21. #include "apr_strings.h"
  22. #include <string.h>
  23. #include "apr_arch_inherit.h"
  24. #include "apr_arch_misc.h"
  25. static char generic_inaddr_any[16] = {0}; /* big enough for IPv4 or IPv6 */
  26. static apr_status_t socket_cleanup(void *sock)
  27. {
  28. apr_socket_t *thesocket = sock;
  29. if (thesocket->socketdes != INVALID_SOCKET) {
  30. if (closesocket(thesocket->socketdes) == SOCKET_ERROR) {
  31. return apr_get_netos_error();
  32. }
  33. thesocket->socketdes = INVALID_SOCKET;
  34. }
  35. #if APR_HAS_SENDFILE
  36. if (thesocket->overlapped) {
  37. CloseHandle(thesocket->overlapped->hEvent);
  38. thesocket->overlapped = NULL;
  39. }
  40. #endif
  41. return APR_SUCCESS;
  42. }
  43. static void set_socket_vars(apr_socket_t *sock, int family, int type, int protocol)
  44. {
  45. sock->type = type;
  46. sock->protocol = protocol;
  47. apr_sockaddr_vars_set(sock->local_addr, family, 0);
  48. apr_sockaddr_vars_set(sock->remote_addr, family, 0);
  49. }
  50. static void alloc_socket(apr_socket_t **new, apr_pool_t *p)
  51. {
  52. *new = (apr_socket_t *)apr_pcalloc(p, sizeof(apr_socket_t));
  53. (*new)->pool = p;
  54. (*new)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->pool,
  55. sizeof(apr_sockaddr_t));
  56. (*new)->local_addr->pool = p;
  57. (*new)->remote_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->pool,
  58. sizeof(apr_sockaddr_t));
  59. (*new)->remote_addr->pool = p;
  60. (*new)->remote_addr_unknown = 1;
  61. /* Create a pollset with room for one descriptor. */
  62. /* ### check return codes */
  63. (void) apr_pollset_create(&(*new)->pollset, 1, p, 0);
  64. }
  65. APR_DECLARE(apr_status_t) apr_socket_protocol_get(apr_socket_t *sock,
  66. int *protocol)
  67. {
  68. *protocol = sock->protocol;
  69. return APR_SUCCESS;
  70. }
  71. APR_DECLARE(apr_status_t) apr_socket_create(apr_socket_t **new, int family,
  72. int type, int protocol,
  73. apr_pool_t *cont)
  74. {
  75. int downgrade = (family == AF_UNSPEC);
  76. if (family == AF_UNSPEC) {
  77. #if APR_HAVE_IPV6
  78. family = AF_INET6;
  79. #else
  80. family = AF_INET;
  81. #endif
  82. }
  83. alloc_socket(new, cont);
  84. /* For right now, we are not using socket groups. We may later.
  85. * No flags to use when creating a socket, so use 0 for that parameter as well.
  86. */
  87. (*new)->socketdes = socket(family, type, protocol);
  88. #if APR_HAVE_IPV6
  89. if ((*new)->socketdes == INVALID_SOCKET && downgrade) {
  90. family = AF_INET;
  91. (*new)->socketdes = socket(family, type, protocol);
  92. }
  93. #endif
  94. if ((*new)->socketdes == INVALID_SOCKET) {
  95. return apr_get_netos_error();
  96. }
  97. #ifdef WIN32
  98. /* Socket handles are never truly inheritable, there are too many
  99. * bugs associated. WSADuplicateSocket will copy them, but for our
  100. * purposes, always transform the socket() created as a non-inherited
  101. * handle
  102. */
  103. #if APR_HAS_UNICODE_FS
  104. IF_WIN_OS_IS_UNICODE {
  105. /* A different approach. Many users report errors such as
  106. * (32538)An operation was attempted on something that is not
  107. * a socket. : Parent: WSADuplicateSocket failed...
  108. *
  109. * This appears that the duplicated handle is no longer recognized
  110. * as a socket handle. SetHandleInformation should overcome that
  111. * problem by not altering the handle identifier. But this won't
  112. * work on 9x - it's unsupported.
  113. */
  114. SetHandleInformation((HANDLE) (*new)->socketdes,
  115. HANDLE_FLAG_INHERIT, 0);
  116. }
  117. #endif
  118. #if APR_HAS_ANSI_FS
  119. ELSE_WIN_OS_IS_ANSI {
  120. HANDLE hProcess = GetCurrentProcess();
  121. HANDLE dup;
  122. if (DuplicateHandle(hProcess, (HANDLE) (*new)->socketdes, hProcess,
  123. &dup, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
  124. closesocket((*new)->socketdes);
  125. (*new)->socketdes = (SOCKET) dup;
  126. }
  127. }
  128. #endif
  129. #endif /* def WIN32 */
  130. set_socket_vars(*new, family, type, protocol);
  131. (*new)->timeout = -1;
  132. (*new)->disconnected = 0;
  133. apr_pool_cleanup_register((*new)->pool, (void *)(*new),
  134. socket_cleanup, apr_pool_cleanup_null);
  135. return APR_SUCCESS;
  136. }
  137. APR_DECLARE(apr_status_t) apr_socket_shutdown(apr_socket_t *thesocket,
  138. apr_shutdown_how_e how)
  139. {
  140. int winhow = 0;
  141. #ifdef SD_RECEIVE
  142. switch (how) {
  143. case APR_SHUTDOWN_READ: {
  144. winhow = SD_RECEIVE;
  145. break;
  146. }
  147. case APR_SHUTDOWN_WRITE: {
  148. winhow = SD_SEND;
  149. break;
  150. }
  151. case APR_SHUTDOWN_READWRITE: {
  152. winhow = SD_BOTH;
  153. break;
  154. }
  155. default:
  156. return APR_BADARG;
  157. }
  158. #endif
  159. if (shutdown(thesocket->socketdes, winhow) == 0) {
  160. return APR_SUCCESS;
  161. }
  162. else {
  163. return apr_get_netos_error();
  164. }
  165. }
  166. APR_DECLARE(apr_status_t) apr_socket_close(apr_socket_t *thesocket)
  167. {
  168. apr_pool_cleanup_kill(thesocket->pool, thesocket, socket_cleanup);
  169. return socket_cleanup(thesocket);
  170. }
  171. APR_DECLARE(apr_status_t) apr_socket_bind(apr_socket_t *sock,
  172. apr_sockaddr_t *sa)
  173. {
  174. if (bind(sock->socketdes,
  175. (struct sockaddr *)&sa->sa,
  176. sa->salen) == -1) {
  177. return apr_get_netos_error();
  178. }
  179. else {
  180. sock->local_addr = sa;
  181. if (sock->local_addr->sa.sin.sin_port == 0) {
  182. sock->local_port_unknown = 1; /* ephemeral port */
  183. }
  184. return APR_SUCCESS;
  185. }
  186. }
  187. APR_DECLARE(apr_status_t) apr_socket_listen(apr_socket_t *sock,
  188. apr_int32_t backlog)
  189. {
  190. if (listen(sock->socketdes, backlog) == SOCKET_ERROR)
  191. return apr_get_netos_error();
  192. else
  193. return APR_SUCCESS;
  194. }
  195. APR_DECLARE(apr_status_t) apr_socket_accept(apr_socket_t **new,
  196. apr_socket_t *sock, apr_pool_t *p)
  197. {
  198. SOCKET s;
  199. #if APR_HAVE_IPV6
  200. struct sockaddr_storage sa;
  201. #else
  202. struct sockaddr sa;
  203. #endif
  204. int salen = sizeof(sock->remote_addr->sa);
  205. /* Don't allocate the memory until after we call accept. This allows
  206. us to work with nonblocking sockets. */
  207. s = accept(sock->socketdes, (struct sockaddr *)&sa, &salen);
  208. if (s == INVALID_SOCKET) {
  209. return apr_get_netos_error();
  210. }
  211. alloc_socket(new, p);
  212. set_socket_vars(*new, sock->local_addr->sa.sin.sin_family, SOCK_STREAM,
  213. sock->protocol);
  214. (*new)->timeout = -1;
  215. (*new)->disconnected = 0;
  216. (*new)->socketdes = s;
  217. /* XXX next line looks bogus w.r.t. AF_INET6 support */
  218. (*new)->remote_addr->salen = sizeof((*new)->remote_addr->sa);
  219. memcpy (&(*new)->remote_addr->sa, &sa, salen);
  220. *(*new)->local_addr = *sock->local_addr;
  221. /* The above assignment just overwrote the pool entry. Setting the local_addr
  222. pool for the accepted socket back to what it should be. Otherwise all
  223. allocations for this socket will come from a server pool that is not
  224. freed until the process goes down.*/
  225. (*new)->local_addr->pool = p;
  226. /* fix up any pointers which are no longer valid */
  227. if (sock->local_addr->sa.sin.sin_family == AF_INET) {
  228. (*new)->local_addr->ipaddr_ptr = &(*new)->local_addr->sa.sin.sin_addr;
  229. }
  230. #if APR_HAVE_IPV6
  231. else if (sock->local_addr->sa.sin.sin_family == AF_INET6) {
  232. (*new)->local_addr->ipaddr_ptr = &(*new)->local_addr->sa.sin6.sin6_addr;
  233. }
  234. #endif
  235. (*new)->remote_addr->port = ntohs((*new)->remote_addr->sa.sin.sin_port);
  236. if (sock->local_port_unknown) {
  237. /* not likely for a listening socket, but theoretically possible :) */
  238. (*new)->local_port_unknown = 1;
  239. }
  240. #if APR_TCP_NODELAY_INHERITED
  241. if (apr_is_option_set(sock, APR_TCP_NODELAY) == 1) {
  242. apr_set_option(*new, APR_TCP_NODELAY, 1);
  243. }
  244. #endif /* TCP_NODELAY_INHERITED */
  245. #if APR_O_NONBLOCK_INHERITED
  246. if (apr_is_option_set(sock, APR_SO_NONBLOCK) == 1) {
  247. apr_set_option(*new, APR_SO_NONBLOCK, 1);
  248. }
  249. #endif /* APR_O_NONBLOCK_INHERITED */
  250. if (sock->local_interface_unknown ||
  251. !memcmp(sock->local_addr->ipaddr_ptr,
  252. generic_inaddr_any,
  253. sock->local_addr->ipaddr_len)) {
  254. /* If the interface address inside the listening socket's local_addr wasn't
  255. * up-to-date, we don't know local interface of the connected socket either.
  256. *
  257. * If the listening socket was not bound to a specific interface, we
  258. * don't know the local_addr of the connected socket.
  259. */
  260. (*new)->local_interface_unknown = 1;
  261. }
  262. apr_pool_cleanup_register((*new)->pool, (void *)(*new),
  263. socket_cleanup, apr_pool_cleanup_null);
  264. return APR_SUCCESS;
  265. }
  266. APR_DECLARE(apr_status_t) apr_socket_connect(apr_socket_t *sock,
  267. apr_sockaddr_t *sa)
  268. {
  269. apr_status_t rv;
  270. if ((sock->socketdes == INVALID_SOCKET) || (!sock->local_addr)) {
  271. return APR_ENOTSOCK;
  272. }
  273. if (connect(sock->socketdes, (const struct sockaddr *)&sa->sa.sin,
  274. sa->salen) == SOCKET_ERROR) {
  275. int rc;
  276. struct timeval tv, *tvptr;
  277. fd_set wfdset, efdset;
  278. rv = apr_get_netos_error();
  279. if (rv != APR_FROM_OS_ERROR(WSAEWOULDBLOCK)) {
  280. return rv;
  281. }
  282. if (sock->timeout == 0) {
  283. /* Tell the app that the connect is in progress...
  284. * Gotta play some games here. connect on Unix will return
  285. * EINPROGRESS under the same circumstances that Windows
  286. * returns WSAEWOULDBLOCK. Do some adhoc canonicalization...
  287. */
  288. return APR_FROM_OS_ERROR(WSAEINPROGRESS);
  289. }
  290. /* wait for the connect to complete or timeout */
  291. FD_ZERO(&wfdset);
  292. FD_SET(sock->socketdes, &wfdset);
  293. FD_ZERO(&efdset);
  294. FD_SET(sock->socketdes, &efdset);
  295. if (sock->timeout < 0) {
  296. tvptr = NULL;
  297. }
  298. else {
  299. /* casts for winsock/timeval definition */
  300. tv.tv_sec = (long)apr_time_sec(sock->timeout);
  301. tv.tv_usec = (int)apr_time_usec(sock->timeout);
  302. tvptr = &tv;
  303. }
  304. rc = select(FD_SETSIZE+1, NULL, &wfdset, &efdset, tvptr);
  305. if (rc == SOCKET_ERROR) {
  306. return apr_get_netos_error();
  307. }
  308. else if (!rc) {
  309. return APR_FROM_OS_ERROR(WSAETIMEDOUT);
  310. }
  311. /* Evaluate the efdset */
  312. if (FD_ISSET(sock->socketdes, &efdset)) {
  313. /* The connect failed. */
  314. int rclen = sizeof(rc);
  315. if (getsockopt(sock->socketdes, SOL_SOCKET, SO_ERROR, (char*) &rc, &rclen)) {
  316. return apr_get_netos_error();
  317. }
  318. return APR_FROM_OS_ERROR(rc);
  319. }
  320. }
  321. /* connect was OK .. amazing */
  322. sock->remote_addr = sa;
  323. if (sock->local_addr->sa.sin.sin_port == 0) {
  324. sock->local_port_unknown = 1;
  325. }
  326. if (!memcmp(sock->local_addr->ipaddr_ptr,
  327. generic_inaddr_any,
  328. sock->local_addr->ipaddr_len)) {
  329. /* not bound to specific local interface; connect() had to assign
  330. * one for the socket
  331. */
  332. sock->local_interface_unknown = 1;
  333. }
  334. return APR_SUCCESS;
  335. }
  336. APR_DECLARE(apr_status_t) apr_socket_type_get(apr_socket_t *sock, int *type)
  337. {
  338. *type = sock->type;
  339. return APR_SUCCESS;
  340. }
  341. APR_DECLARE(apr_status_t) apr_socket_data_get(void **data, const char *key,
  342. apr_socket_t *sock)
  343. {
  344. sock_userdata_t *cur = sock->userdata;
  345. *data = NULL;
  346. while (cur) {
  347. if (!strcmp(cur->key, key)) {
  348. *data = cur->data;
  349. break;
  350. }
  351. cur = cur->next;
  352. }
  353. return APR_SUCCESS;
  354. }
  355. APR_DECLARE(apr_status_t) apr_socket_data_set(apr_socket_t *sock, void *data,
  356. const char *key,
  357. apr_status_t (*cleanup)(void *))
  358. {
  359. sock_userdata_t *new = apr_palloc(sock->pool, sizeof(sock_userdata_t));
  360. new->key = apr_pstrdup(sock->pool, key);
  361. new->data = data;
  362. new->next = sock->userdata;
  363. sock->userdata = new;
  364. if (cleanup) {
  365. apr_pool_cleanup_register(sock->pool, data, cleanup, cleanup);
  366. }
  367. return APR_SUCCESS;
  368. }
  369. APR_DECLARE(apr_status_t) apr_os_sock_get(apr_os_sock_t *thesock,
  370. apr_socket_t *sock)
  371. {
  372. *thesock = sock->socketdes;
  373. return APR_SUCCESS;
  374. }
  375. APR_DECLARE(apr_status_t) apr_os_sock_make(apr_socket_t **apr_sock,
  376. apr_os_sock_info_t *os_sock_info,
  377. apr_pool_t *cont)
  378. {
  379. alloc_socket(apr_sock, cont);
  380. set_socket_vars(*apr_sock, os_sock_info->family, os_sock_info->type, os_sock_info->protocol);
  381. (*apr_sock)->timeout = -1;
  382. (*apr_sock)->disconnected = 0;
  383. (*apr_sock)->socketdes = *os_sock_info->os_sock;
  384. if (os_sock_info->local) {
  385. memcpy(&(*apr_sock)->local_addr->sa.sin,
  386. os_sock_info->local,
  387. (*apr_sock)->local_addr->salen);
  388. (*apr_sock)->local_addr->pool = cont;
  389. /* XXX IPv6 - this assumes sin_port and sin6_port at same offset */
  390. (*apr_sock)->local_addr->port = ntohs((*apr_sock)->local_addr->sa.sin.sin_port);
  391. }
  392. else {
  393. (*apr_sock)->local_port_unknown = (*apr_sock)->local_interface_unknown = 1;
  394. }
  395. if (os_sock_info->remote) {
  396. memcpy(&(*apr_sock)->remote_addr->sa.sin,
  397. os_sock_info->remote,
  398. (*apr_sock)->remote_addr->salen);
  399. (*apr_sock)->remote_addr->pool = cont;
  400. /* XXX IPv6 - this assumes sin_port and sin6_port at same offset */
  401. (*apr_sock)->remote_addr->port = ntohs((*apr_sock)->remote_addr->sa.sin.sin_port);
  402. }
  403. else {
  404. (*apr_sock)->remote_addr_unknown = 1;
  405. }
  406. apr_pool_cleanup_register((*apr_sock)->pool, (void *)(*apr_sock),
  407. socket_cleanup, apr_pool_cleanup_null);
  408. return APR_SUCCESS;
  409. }
  410. APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock,
  411. apr_os_sock_t *thesock,
  412. apr_pool_t *cont)
  413. {
  414. if ((*sock) == NULL) {
  415. alloc_socket(sock, cont);
  416. /* XXX figure out the actual socket type here */
  417. /* *or* just decide that apr_os_sock_put() has to be told the family and type */
  418. set_socket_vars(*sock, AF_INET, SOCK_STREAM, 0);
  419. (*sock)->timeout = -1;
  420. (*sock)->disconnected = 0;
  421. }
  422. (*sock)->local_port_unknown = (*sock)->local_interface_unknown = 1;
  423. (*sock)->remote_addr_unknown = 1;
  424. (*sock)->socketdes = *thesock;
  425. return APR_SUCCESS;
  426. }
  427. /* Sockets cannot be inherited through the standard sockets
  428. * inheritence. WSADuplicateSocket must be used.
  429. * This is not trivial to implement.
  430. */
  431. APR_DECLARE(apr_status_t) apr_socket_inherit_set(apr_socket_t *socket)
  432. {
  433. return APR_ENOTIMPL;
  434. }
  435. APR_DECLARE(apr_status_t) apr_socket_inherit_unset(apr_socket_t *socket)
  436. {
  437. return APR_ENOTIMPL;
  438. }
  439. APR_POOL_IMPLEMENT_ACCESSOR(socket);