VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/NAT/RTWinSocketPair.cpp@ 52934

Last change on this file since 52934 was 48956, checked in by vboxsync, 11 years ago

NetworkServices: Whitespace (including tabs!) and svn:keywords cleanups by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.9 KB
Line 
1#include <iprt/asm.h>
2#include <iprt/assert.h>
3#include <iprt/cdefs.h>
4#include <iprt/err.h>
5
6#include <VBox/err.h>
7
8#include <Winsock2.h>
9#include <Windows.h>
10
11#include <stdio.h>
12#include <iprt/log.h>
13
14extern "C" int RTWinSocketPair(int domain, int type, int protocol, SOCKET socket_vector[2])
15{
16 LogFlowFunc(("ENTER: domain:%d, type:%d, protocol:%d, socket_vector:%p\n",
17 domain, type, protocol, socket_vector));
18 switch (domain)
19 {
20 case AF_INET:
21 break;
22 case AF_INET6: /* I dobt we really need it. */
23 default:
24 AssertMsgFailedReturn(("Unsuported domain:%d\n", domain),
25 VERR_INVALID_PARAMETER);
26 }
27
28 switch(type)
29 {
30 case SOCK_STREAM:
31 case SOCK_DGRAM:
32 break;
33 default:
34 AssertMsgFailedReturn(("Unsuported type:%d\n", type),
35 VERR_INVALID_PARAMETER);
36 }
37
38 AssertPtrReturn(socket_vector, VERR_INVALID_PARAMETER);
39 if (!socket_vector)
40 return VERR_INVALID_PARAMETER;
41
42 socket_vector[0] = socket_vector[1] = INVALID_SOCKET;
43
44 SOCKET listener = INVALID_SOCKET;
45
46 union {
47 struct sockaddr_in in_addr;
48 struct sockaddr addr;
49 } sa[2];
50
51 int cb = sizeof(sa);
52 memset(&sa, 0, cb);
53
54 sa[0].in_addr.sin_family = domain;
55 sa[0].in_addr.sin_addr.s_addr = RT_H2N_U32(INADDR_LOOPBACK);
56 sa[0].in_addr.sin_port = 0;
57 cb = sizeof(sa[0]);
58
59 if (type == SOCK_STREAM)
60 {
61 listener = WSASocket(domain, type, protocol, 0, NULL, 0);
62
63 if (listener == INVALID_SOCKET)
64 {
65 return VERR_INTERNAL_ERROR;
66 }
67
68 int reuse = 1;
69 cb = sizeof(int);
70 int rc = setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, cb);
71
72 if (rc)
73 {
74 goto close_socket;
75 }
76
77 cb = sizeof(sa[0]);
78 rc = bind(listener, &sa[0].addr, cb);
79 if(rc)
80 {
81 goto close_socket;
82 }
83
84 memset(&sa[0], 0, cb);
85 rc = getsockname(listener, &sa[0].addr, &cb);
86 if (rc)
87 {
88 goto close_socket;
89 }
90
91 rc = listen(listener, 1);
92 if (rc)
93 {
94 goto close_socket;
95 }
96
97 socket_vector[0] = WSASocket(domain, type, protocol, 0, NULL, 0);
98 if (socket_vector[0] == INVALID_SOCKET)
99 {
100 goto close_socket;
101 }
102
103 rc = connect(socket_vector[0], &sa[0].addr, cb);
104 if (rc)
105 goto close_socket;
106
107
108 socket_vector[1] = accept(listener, NULL, NULL);
109 if (socket_vector[1] == INVALID_SOCKET)
110 {
111 goto close_socket;
112 }
113
114 closesocket(listener);
115 }
116 else
117 {
118 socket_vector[0] = WSASocket(domain, type, protocol, 0, NULL, 0);
119
120 cb = sizeof(sa[0]);
121 int rc = bind(socket_vector[0], &sa[0].addr, cb);
122 Assert(rc != SOCKET_ERROR);
123 if (rc == SOCKET_ERROR)
124 {
125 goto close_socket;
126 }
127
128 sa[1].in_addr.sin_family = domain;
129 sa[1].in_addr.sin_addr.s_addr = RT_H2N_U32(INADDR_LOOPBACK);
130 sa[1].in_addr.sin_port = 0;
131
132 socket_vector[1] = WSASocket(domain, type, protocol, 0, NULL, 0);
133 rc = bind(socket_vector[1], &sa[1].addr, cb);
134 Assert(rc != SOCKET_ERROR);
135 if (rc == SOCKET_ERROR)
136 {
137 goto close_socket;
138 }
139
140 {
141 u_long mode = 0;
142 rc = ioctlsocket(socket_vector[0], FIONBIO, &mode);
143 AssertMsgReturn(rc != SOCKET_ERROR,
144 ("ioctl error: %d\n", WSAGetLastError()),
145 VERR_INTERNAL_ERROR);
146
147 rc = ioctlsocket(socket_vector[1], FIONBIO, &mode);
148 AssertMsgReturn(rc != SOCKET_ERROR,
149 ("ioctl error: %d\n", WSAGetLastError()),
150 VERR_INTERNAL_ERROR);
151 }
152
153 memset(&sa, 0, 2 * cb);
154 rc = getsockname(socket_vector[0], &sa[0].addr, &cb);
155 Assert(rc != SOCKET_ERROR);
156 if (rc == SOCKET_ERROR)
157 {
158 goto close_socket;
159 }
160
161 rc = getsockname(socket_vector[1], &sa[1].addr, &cb);
162 Assert(rc != SOCKET_ERROR);
163 if (rc == SOCKET_ERROR)
164 {
165 goto close_socket;
166 }
167
168 rc = connect(socket_vector[0], &sa[1].addr, cb);
169 Assert(rc != SOCKET_ERROR);
170 if (rc == SOCKET_ERROR)
171 {
172 goto close_socket;
173 }
174
175 rc = connect(socket_vector[1], &sa[0].addr, cb);
176 Assert(rc != SOCKET_ERROR);
177 if (rc == SOCKET_ERROR)
178 {
179 goto close_socket;
180 }
181 }
182 LogFlowFuncLeaveRC(VINF_SUCCESS);
183 return VINF_SUCCESS;
184
185close_socket:
186 if (listener != INVALID_SOCKET)
187 closesocket(listener);
188
189 if (socket_vector[0] != INVALID_SOCKET)
190 closesocket(socket_vector[0]);
191
192 if (socket_vector[1] != INVALID_SOCKET)
193 closesocket(socket_vector[1]);
194
195 LogFlowFuncLeaveRC(VERR_INTERNAL_ERROR);
196 return VERR_INTERNAL_ERROR;
197}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette