aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/mhd_itc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/mhd_itc.c')
-rw-r--r--src/microhttpd/mhd_itc.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/microhttpd/mhd_itc.c b/src/microhttpd/mhd_itc.c
new file mode 100644
index 00000000..cd0e5371
--- /dev/null
+++ b/src/microhttpd/mhd_itc.c
@@ -0,0 +1,108 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2016 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19*/
20
21/**
22 * @file microhttpd/mhd_sockets.c
23 * @brief Implementation of inter-thread communication functions
24 * @author Karlson2k (Evgeny Grin)
25 */
26
27#include "mhd_itc.h"
28
29#if defined(_WIN32) && !defined(__CYGWIN__)
30/**
31 * Create pair of mutually connected TCP/IP sockets on loopback address
32 * @param sockets_pair array to receive resulted sockets
33 * @return zero on success, -1 otherwise
34 */
35int MHD_W32_pair_of_sockets_(SOCKET sockets_pair[2])
36{
37 int i;
38 if (!sockets_pair)
39 {
40 errno = EINVAL;
41 return -1;
42 }
43
44#define PAIRMAXTRYIES 800
45 for (i = 0; i < PAIRMAXTRYIES; i++)
46 {
47 struct sockaddr_in listen_addr;
48 SOCKET listen_s;
49 static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */
50 int addr_len = c_addinlen;
51 int opt = 1;
52
53 listen_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
54 if (INVALID_SOCKET == listen_s)
55 break; /* can't create even single socket */
56
57 listen_addr.sin_family = AF_INET;
58 listen_addr.sin_port = htons(0);
59 listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
60 if (0 == bind(listen_s, (struct sockaddr*) &listen_addr, c_addinlen)
61 && 0 == listen(listen_s, 1)
62 && 0 == getsockname(listen_s, (struct sockaddr*) &listen_addr,
63 &addr_len))
64 {
65 SOCKET client_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
66 if (INVALID_SOCKET != client_s)
67 {
68 if (0 == ioctlsocket(client_s, FIONBIO, (u_long*) &opt)
69 && (0 == connect(client_s, (struct sockaddr*) &listen_addr, c_addinlen)
70 || WSAGetLastError() == WSAEWOULDBLOCK))
71 {
72 struct sockaddr_in accepted_from_addr;
73 SOCKET server_s;
74 addr_len = c_addinlen;
75 server_s = accept(listen_s,
76 (struct sockaddr*) &accepted_from_addr, &addr_len);
77 if (INVALID_SOCKET != server_s)
78 {
79 struct sockaddr_in client_addr;
80 addr_len = c_addinlen;
81 opt = 0;
82 if (0 == getsockname(client_s, (struct sockaddr*) &client_addr, &addr_len)
83 && accepted_from_addr.sin_family == client_addr.sin_family
84 && accepted_from_addr.sin_port == client_addr.sin_port
85 && accepted_from_addr.sin_addr.s_addr == client_addr.sin_addr.s_addr
86 && 0 == ioctlsocket(client_s, FIONBIO, (u_long*) &opt)
87 && 0 == ioctlsocket(server_s, FIONBIO, (u_long*) &opt))
88 {
89 closesocket(listen_s);
90 sockets_pair[0] = client_s;
91 sockets_pair[1] = server_s;
92 return 0;
93 }
94 closesocket(server_s);
95 }
96 }
97 closesocket(client_s);
98 }
99 }
100 closesocket(listen_s);
101 }
102
103 sockets_pair[0] = INVALID_SOCKET;
104 sockets_pair[1] = INVALID_SOCKET;
105 return -1;
106}
107
108#endif /* _WIN32 && ! __CYGWIN__ */