|
1 /*- |
|
2 * Copyright (c) 2011-2012 Irene Ruengeler |
|
3 * Copyright (c) 2011-2012 Michael Tuexen |
|
4 * All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions |
|
8 * are met: |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * 2. Redistributions in binary form must reproduce the above copyright |
|
12 * notice, this list of conditions and the following disclaimer in the |
|
13 * documentation and/or other materials provided with the distribution. |
|
14 * |
|
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
|
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
|
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
25 * SUCH DAMAGE. |
|
26 * |
|
27 */ |
|
28 |
|
29 |
|
30 #ifdef _WIN32 |
|
31 #include <netinet/sctp_pcb.h> |
|
32 #include <sys/timeb.h> |
|
33 #include <iphlpapi.h> |
|
34 #pragma comment(lib, "IPHLPAPI.lib") |
|
35 #endif |
|
36 #include <netinet/sctp_os_userspace.h> |
|
37 |
|
38 #ifndef _WIN32 |
|
39 int |
|
40 sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) |
|
41 { |
|
42 struct ifreq ifr; |
|
43 int fd; |
|
44 |
|
45 if_indextoname(if_index, ifr.ifr_name); |
|
46 /* TODO can I use the raw socket here and not have to open a new one with each query? */ |
|
47 if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) |
|
48 return (0); |
|
49 if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { |
|
50 close(fd); |
|
51 return (0); |
|
52 } |
|
53 close(fd); |
|
54 return ifr.ifr_mtu; |
|
55 } |
|
56 #endif |
|
57 |
|
58 #ifdef _WIN32 |
|
59 int |
|
60 sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) |
|
61 { |
|
62 PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt; |
|
63 DWORD AdapterAddrsSize, Err; |
|
64 |
|
65 AdapterAddrsSize = 0; |
|
66 if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { |
|
67 if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { |
|
68 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() sizing failed with error code %d, AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); |
|
69 return (-1); |
|
70 } |
|
71 } |
|
72 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { |
|
73 SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); |
|
74 return (-1); |
|
75 } |
|
76 if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { |
|
77 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() failed with error code %d\n", Err); |
|
78 return (-1); |
|
79 } |
|
80 for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) { |
|
81 if (pAdapt->IfIndex == if_index) |
|
82 return (pAdapt->Mtu); |
|
83 } |
|
84 return (0); |
|
85 } |
|
86 |
|
87 void |
|
88 getwintimeofday(struct timeval *tv) |
|
89 { |
|
90 struct timeb tb; |
|
91 |
|
92 ftime(&tb); |
|
93 tv->tv_sec = tb.time; |
|
94 tv->tv_usec = tb.millitm * 1000; |
|
95 } |
|
96 |
|
97 int |
|
98 Win_getifaddrs(struct ifaddrs** interfaces) |
|
99 { |
|
100 #if defined(INET) || defined(INET6) |
|
101 DWORD Err, AdapterAddrsSize; |
|
102 int count; |
|
103 PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt; |
|
104 struct ifaddrs *ifa; |
|
105 #endif |
|
106 #if defined(INET) |
|
107 struct sockaddr_in *addr; |
|
108 #endif |
|
109 #if defined(INET6) |
|
110 struct sockaddr_in6 *addr6; |
|
111 #endif |
|
112 #if defined(INET) || defined(INET6) |
|
113 count = 0; |
|
114 #endif |
|
115 #if defined(INET) |
|
116 AdapterAddrsSize = 0; |
|
117 if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { |
|
118 if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { |
|
119 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV4Addresses() sizing failed with error code %d and AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); |
|
120 return (-1); |
|
121 } |
|
122 } |
|
123 /* Allocate memory from sizing information */ |
|
124 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { |
|
125 SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); |
|
126 return (-1); |
|
127 } |
|
128 /* Get actual adapter information */ |
|
129 if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { |
|
130 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV4Addresses() failed with error code %d\n", Err); |
|
131 return (-1); |
|
132 } |
|
133 /* Enumerate through each returned adapter and save its information */ |
|
134 for (pAdapt = pAdapterAddrs, count; pAdapt; pAdapt = pAdapt->Next, count++) { |
|
135 addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); |
|
136 ifa = (struct ifaddrs *)malloc(sizeof(struct ifaddrs)); |
|
137 if ((addr == NULL) || (ifa == NULL)) { |
|
138 SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n"); |
|
139 return (-1); |
|
140 } |
|
141 ifa->ifa_name = strdup(pAdapt->AdapterName); |
|
142 ifa->ifa_flags = pAdapt->Flags; |
|
143 ifa->ifa_addr = (struct sockaddr *)addr; |
|
144 memcpy(&addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in)); |
|
145 interfaces[count] = ifa; |
|
146 } |
|
147 #endif |
|
148 #if defined(INET6) |
|
149 if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { |
|
150 AdapterAddrsSize = 0; |
|
151 if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { |
|
152 if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { |
|
153 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV6Addresses() sizing failed with error code %d AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); |
|
154 return (-1); |
|
155 } |
|
156 } |
|
157 /* Allocate memory from sizing information */ |
|
158 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { |
|
159 SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); |
|
160 return (-1); |
|
161 } |
|
162 /* Get actual adapter information */ |
|
163 if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { |
|
164 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV6Addresses() failed with error code %d\n", Err); |
|
165 return (-1); |
|
166 } |
|
167 /* Enumerate through each returned adapter and save its information */ |
|
168 for (pAdapt = pAdapterAddrs, count; pAdapt; pAdapt = pAdapt->Next, count++) { |
|
169 addr6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6)); |
|
170 ifa = (struct ifaddrs *)malloc(sizeof(struct ifaddrs)); |
|
171 if ((addr6 == NULL) || (ifa == NULL)) { |
|
172 SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n"); |
|
173 return (-1); |
|
174 } |
|
175 ifa->ifa_name = strdup(pAdapt->AdapterName); |
|
176 ifa->ifa_flags = pAdapt->Flags; |
|
177 ifa->ifa_addr = (struct sockaddr *)addr6; |
|
178 memcpy(&addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6)); |
|
179 interfaces[count] = ifa; |
|
180 } |
|
181 } |
|
182 #endif |
|
183 return (0); |
|
184 } |
|
185 |
|
186 int |
|
187 win_if_nametoindex(const char *ifname) |
|
188 { |
|
189 IP_ADAPTER_ADDRESSES *addresses, *addr; |
|
190 ULONG status, size; |
|
191 int index = 0; |
|
192 |
|
193 if (!ifname) { |
|
194 return 0; |
|
195 } |
|
196 |
|
197 size = 0; |
|
198 status = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size); |
|
199 if (status != ERROR_BUFFER_OVERFLOW) { |
|
200 return 0; |
|
201 } |
|
202 addresses = malloc(size); |
|
203 status = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &size); |
|
204 if (status == ERROR_SUCCESS) { |
|
205 for (addr = addresses; addr; addr = addr->Next) { |
|
206 if (addr->AdapterName && !strcmp(ifname, addr->AdapterName)) { |
|
207 index = addr->IfIndex; |
|
208 break; |
|
209 } |
|
210 } |
|
211 } |
|
212 |
|
213 free(addresses); |
|
214 return index; |
|
215 } |
|
216 |
|
217 #if WINVER < 0x0600 |
|
218 /* These functions are written based on the code at |
|
219 * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html |
|
220 * Therefore, for the rest of the file the following applies: |
|
221 * |
|
222 * |
|
223 * Copyright and Licensing Information for ACE(TM), TAO(TM), CIAO(TM), |
|
224 * DAnCE(TM), and CoSMIC(TM) |
|
225 * |
|
226 * [1]ACE(TM), [2]TAO(TM), [3]CIAO(TM), DAnCE(TM), and [4]CoSMIC(TM) |
|
227 * (henceforth referred to as "DOC software") are copyrighted by |
|
228 * [5]Douglas C. Schmidt and his [6]research group at [7]Washington |
|
229 * University, [8]University of California, Irvine, and [9]Vanderbilt |
|
230 * University, Copyright (c) 1993-2012, all rights reserved. Since DOC |
|
231 * software is open-source, freely available software, you are free to |
|
232 * use, modify, copy, and distribute--perpetually and irrevocably--the |
|
233 * DOC software source code and object code produced from the source, as |
|
234 * well as copy and distribute modified versions of this software. You |
|
235 * must, however, include this copyright statement along with any code |
|
236 * built using DOC software that you release. No copyright statement |
|
237 * needs to be provided if you just ship binary executables of your |
|
238 * software products. |
|
239 * |
|
240 * You can use DOC software in commercial and/or binary software releases |
|
241 * and are under no obligation to redistribute any of your source code |
|
242 * that is built using DOC software. Note, however, that you may not |
|
243 * misappropriate the DOC software code, such as copyrighting it yourself |
|
244 * or claiming authorship of the DOC software code, in a way that will |
|
245 * prevent DOC software from being distributed freely using an |
|
246 * open-source development model. You needn't inform anyone that you're |
|
247 * using DOC software in your software, though we encourage you to let |
|
248 * [10]us know so we can promote your project in the [11]DOC software |
|
249 * success stories. |
|
250 * |
|
251 * The [12]ACE, [13]TAO, [14]CIAO, [15]DAnCE, and [16]CoSMIC web sites |
|
252 * are maintained by the [17]DOC Group at the [18]Institute for Software |
|
253 * Integrated Systems (ISIS) and the [19]Center for Distributed Object |
|
254 * Computing of Washington University, St. Louis for the development of |
|
255 * open-source software as part of the open-source software community. |
|
256 * Submissions are provided by the submitter ``as is'' with no warranties |
|
257 * whatsoever, including any warranty of merchantability, noninfringement |
|
258 * of third party intellectual property, or fitness for any particular |
|
259 * purpose. In no event shall the submitter be liable for any direct, |
|
260 * indirect, special, exemplary, punitive, or consequential damages, |
|
261 * including without limitation, lost profits, even if advised of the |
|
262 * possibility of such damages. Likewise, DOC software is provided as is |
|
263 * with no warranties of any kind, including the warranties of design, |
|
264 * merchantability, and fitness for a particular purpose, |
|
265 * noninfringement, or arising from a course of dealing, usage or trade |
|
266 * practice. Washington University, UC Irvine, Vanderbilt University, |
|
267 * their employees, and students shall have no liability with respect to |
|
268 * the infringement of copyrights, trade secrets or any patents by DOC |
|
269 * software or any part thereof. Moreover, in no event will Washington |
|
270 * University, UC Irvine, or Vanderbilt University, their employees, or |
|
271 * students be liable for any lost revenue or profits or other special, |
|
272 * indirect and consequential damages. |
|
273 * |
|
274 * DOC software is provided with no support and without any obligation on |
|
275 * the part of Washington University, UC Irvine, Vanderbilt University, |
|
276 * their employees, or students to assist in its use, correction, |
|
277 * modification, or enhancement. A [20]number of companies around the |
|
278 * world provide commercial support for DOC software, however. DOC |
|
279 * software is Y2K-compliant, as long as the underlying OS platform is |
|
280 * Y2K-compliant. Likewise, DOC software is compliant with the new US |
|
281 * daylight savings rule passed by Congress as "The Energy Policy Act of |
|
282 * 2005," which established new daylight savings times (DST) rules for |
|
283 * the United States that expand DST as of March 2007. Since DOC software |
|
284 * obtains time/date and calendaring information from operating systems |
|
285 * users will not be affected by the new DST rules as long as they |
|
286 * upgrade their operating systems accordingly. |
|
287 * |
|
288 * The names ACE(TM), TAO(TM), CIAO(TM), DAnCE(TM), CoSMIC(TM), |
|
289 * Washington University, UC Irvine, and Vanderbilt University, may not |
|
290 * be used to endorse or promote products or services derived from this |
|
291 * source without express written permission from Washington University, |
|
292 * UC Irvine, or Vanderbilt University. This license grants no permission |
|
293 * to call products or services derived from this source ACE(TM), |
|
294 * TAO(TM), CIAO(TM), DAnCE(TM), or CoSMIC(TM), nor does it grant |
|
295 * permission for the name Washington University, UC Irvine, or |
|
296 * Vanderbilt University to appear in their names. |
|
297 * |
|
298 * If you have any suggestions, additions, comments, or questions, please |
|
299 * let [21]me know. |
|
300 * |
|
301 * [22]Douglas C. Schmidt |
|
302 * |
|
303 * References |
|
304 * |
|
305 * 1. http://www.cs.wustl.edu/~schmidt/ACE.html |
|
306 * 2. http://www.cs.wustl.edu/~schmidt/TAO.html |
|
307 * 3. http://www.dre.vanderbilt.edu/CIAO/ |
|
308 * 4. http://www.dre.vanderbilt.edu/cosmic/ |
|
309 * 5. http://www.dre.vanderbilt.edu/~schmidt/ |
|
310 * 6. http://www.cs.wustl.edu/~schmidt/ACE-members.html |
|
311 * 7. http://www.wustl.edu/ |
|
312 * 8. http://www.uci.edu/ |
|
313 * 9. http://www.vanderbilt.edu/ |
|
314 * 10. mailto:doc_group@cs.wustl.edu |
|
315 * 11. http://www.cs.wustl.edu/~schmidt/ACE-users.html |
|
316 * 12. http://www.cs.wustl.edu/~schmidt/ACE.html |
|
317 * 13. http://www.cs.wustl.edu/~schmidt/TAO.html |
|
318 * 14. http://www.dre.vanderbilt.edu/CIAO/ |
|
319 * 15. http://www.dre.vanderbilt.edu/~schmidt/DOC_ROOT/DAnCE/ |
|
320 * 16. http://www.dre.vanderbilt.edu/cosmic/ |
|
321 * 17. http://www.dre.vanderbilt.edu/ |
|
322 * 18. http://www.isis.vanderbilt.edu/ |
|
323 * 19. http://www.cs.wustl.edu/~schmidt/doc-center.html |
|
324 * 20. http://www.cs.wustl.edu/~schmidt/commercial-support.html |
|
325 * 21. mailto:d.schmidt@vanderbilt.edu |
|
326 * 22. http://www.dre.vanderbilt.edu/~schmidt/ |
|
327 * 23. http://www.cs.wustl.edu/ACE.html |
|
328 */ |
|
329 |
|
330 void |
|
331 InitializeXPConditionVariable(userland_cond_t *cv) |
|
332 { |
|
333 cv->waiters_count = 0; |
|
334 InitializeCriticalSection(&(cv->waiters_count_lock)); |
|
335 cv->events_[C_SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL); |
|
336 cv->events_[C_BROADCAST] = CreateEvent (NULL, TRUE, FALSE, NULL); |
|
337 } |
|
338 |
|
339 void |
|
340 DeleteXPConditionVariable(userland_cond_t *cv) |
|
341 { |
|
342 CloseHandle(cv->events_[C_BROADCAST]); |
|
343 CloseHandle(cv->events_[C_SIGNAL]); |
|
344 DeleteCriticalSection(&(cv->waiters_count_lock)); |
|
345 } |
|
346 |
|
347 int |
|
348 SleepXPConditionVariable(userland_cond_t *cv, userland_mutex_t *mtx) |
|
349 { |
|
350 int result, last_waiter; |
|
351 |
|
352 EnterCriticalSection(&cv->waiters_count_lock); |
|
353 cv->waiters_count++; |
|
354 LeaveCriticalSection(&cv->waiters_count_lock); |
|
355 LeaveCriticalSection (mtx); |
|
356 result = WaitForMultipleObjects(2, cv->events_, FALSE, INFINITE); |
|
357 if (result==-1) { |
|
358 result = GetLastError(); |
|
359 } |
|
360 EnterCriticalSection(&cv->waiters_count_lock); |
|
361 cv->waiters_count--; |
|
362 last_waiter = |
|
363 result == (C_SIGNAL + C_BROADCAST && (cv->waiters_count == 0)); |
|
364 LeaveCriticalSection(&cv->waiters_count_lock); |
|
365 if (last_waiter) |
|
366 ResetEvent(cv->events_[C_BROADCAST]); |
|
367 EnterCriticalSection (mtx); |
|
368 return result; |
|
369 } |
|
370 |
|
371 void |
|
372 WakeAllXPConditionVariable(userland_cond_t *cv) |
|
373 { |
|
374 int have_waiters; |
|
375 EnterCriticalSection(&cv->waiters_count_lock); |
|
376 have_waiters = cv->waiters_count > 0; |
|
377 LeaveCriticalSection(&cv->waiters_count_lock); |
|
378 if (have_waiters) |
|
379 SetEvent (cv->events_[C_BROADCAST]); |
|
380 } |
|
381 #endif |
|
382 #endif |