1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/sctp/src/netinet/sctp_userspace.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,382 @@ 1.4 +/*- 1.5 + * Copyright (c) 2011-2012 Irene Ruengeler 1.6 + * Copyright (c) 2011-2012 Michael Tuexen 1.7 + * All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions 1.11 + * are met: 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 2. Redistributions in binary form must reproduce the above copyright 1.15 + * notice, this list of conditions and the following disclaimer in the 1.16 + * documentation and/or other materials provided with the distribution. 1.17 + * 1.18 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1.19 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.21 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1.22 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1.23 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1.24 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1.25 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1.26 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1.27 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1.28 + * SUCH DAMAGE. 1.29 + * 1.30 + */ 1.31 + 1.32 + 1.33 +#ifdef _WIN32 1.34 +#include <netinet/sctp_pcb.h> 1.35 +#include <sys/timeb.h> 1.36 +#include <iphlpapi.h> 1.37 +#pragma comment(lib, "IPHLPAPI.lib") 1.38 +#endif 1.39 +#include <netinet/sctp_os_userspace.h> 1.40 + 1.41 +#ifndef _WIN32 1.42 +int 1.43 +sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) 1.44 +{ 1.45 + struct ifreq ifr; 1.46 + int fd; 1.47 + 1.48 + if_indextoname(if_index, ifr.ifr_name); 1.49 + /* TODO can I use the raw socket here and not have to open a new one with each query? */ 1.50 + if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) 1.51 + return (0); 1.52 + if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { 1.53 + close(fd); 1.54 + return (0); 1.55 + } 1.56 + close(fd); 1.57 + return ifr.ifr_mtu; 1.58 +} 1.59 +#endif 1.60 + 1.61 +#ifdef _WIN32 1.62 +int 1.63 +sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) 1.64 +{ 1.65 + PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt; 1.66 + DWORD AdapterAddrsSize, Err; 1.67 + 1.68 + AdapterAddrsSize = 0; 1.69 + if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { 1.70 + if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { 1.71 + SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() sizing failed with error code %d, AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); 1.72 + return (-1); 1.73 + } 1.74 + } 1.75 + if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { 1.76 + SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); 1.77 + return (-1); 1.78 + } 1.79 + if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { 1.80 + SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() failed with error code %d\n", Err); 1.81 + return (-1); 1.82 + } 1.83 + for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) { 1.84 + if (pAdapt->IfIndex == if_index) 1.85 + return (pAdapt->Mtu); 1.86 + } 1.87 + return (0); 1.88 +} 1.89 + 1.90 +void 1.91 +getwintimeofday(struct timeval *tv) 1.92 +{ 1.93 + struct timeb tb; 1.94 + 1.95 + ftime(&tb); 1.96 + tv->tv_sec = tb.time; 1.97 + tv->tv_usec = tb.millitm * 1000; 1.98 +} 1.99 + 1.100 +int 1.101 +Win_getifaddrs(struct ifaddrs** interfaces) 1.102 +{ 1.103 +#if defined(INET) || defined(INET6) 1.104 + DWORD Err, AdapterAddrsSize; 1.105 + int count; 1.106 + PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt; 1.107 + struct ifaddrs *ifa; 1.108 +#endif 1.109 +#if defined(INET) 1.110 + struct sockaddr_in *addr; 1.111 +#endif 1.112 +#if defined(INET6) 1.113 + struct sockaddr_in6 *addr6; 1.114 +#endif 1.115 +#if defined(INET) || defined(INET6) 1.116 + count = 0; 1.117 +#endif 1.118 +#if defined(INET) 1.119 + AdapterAddrsSize = 0; 1.120 + if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { 1.121 + if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { 1.122 + SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV4Addresses() sizing failed with error code %d and AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); 1.123 + return (-1); 1.124 + } 1.125 + } 1.126 + /* Allocate memory from sizing information */ 1.127 + if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { 1.128 + SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); 1.129 + return (-1); 1.130 + } 1.131 + /* Get actual adapter information */ 1.132 + if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { 1.133 + SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV4Addresses() failed with error code %d\n", Err); 1.134 + return (-1); 1.135 + } 1.136 + /* Enumerate through each returned adapter and save its information */ 1.137 + for (pAdapt = pAdapterAddrs, count; pAdapt; pAdapt = pAdapt->Next, count++) { 1.138 + addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); 1.139 + ifa = (struct ifaddrs *)malloc(sizeof(struct ifaddrs)); 1.140 + if ((addr == NULL) || (ifa == NULL)) { 1.141 + SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n"); 1.142 + return (-1); 1.143 + } 1.144 + ifa->ifa_name = strdup(pAdapt->AdapterName); 1.145 + ifa->ifa_flags = pAdapt->Flags; 1.146 + ifa->ifa_addr = (struct sockaddr *)addr; 1.147 + memcpy(&addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in)); 1.148 + interfaces[count] = ifa; 1.149 + } 1.150 +#endif 1.151 +#if defined(INET6) 1.152 + if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { 1.153 + AdapterAddrsSize = 0; 1.154 + if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { 1.155 + if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { 1.156 + SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV6Addresses() sizing failed with error code %d AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); 1.157 + return (-1); 1.158 + } 1.159 + } 1.160 + /* Allocate memory from sizing information */ 1.161 + if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { 1.162 + SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); 1.163 + return (-1); 1.164 + } 1.165 + /* Get actual adapter information */ 1.166 + if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { 1.167 + SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV6Addresses() failed with error code %d\n", Err); 1.168 + return (-1); 1.169 + } 1.170 + /* Enumerate through each returned adapter and save its information */ 1.171 + for (pAdapt = pAdapterAddrs, count; pAdapt; pAdapt = pAdapt->Next, count++) { 1.172 + addr6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6)); 1.173 + ifa = (struct ifaddrs *)malloc(sizeof(struct ifaddrs)); 1.174 + if ((addr6 == NULL) || (ifa == NULL)) { 1.175 + SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n"); 1.176 + return (-1); 1.177 + } 1.178 + ifa->ifa_name = strdup(pAdapt->AdapterName); 1.179 + ifa->ifa_flags = pAdapt->Flags; 1.180 + ifa->ifa_addr = (struct sockaddr *)addr6; 1.181 + memcpy(&addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6)); 1.182 + interfaces[count] = ifa; 1.183 + } 1.184 + } 1.185 +#endif 1.186 + return (0); 1.187 +} 1.188 + 1.189 +int 1.190 +win_if_nametoindex(const char *ifname) 1.191 +{ 1.192 + IP_ADAPTER_ADDRESSES *addresses, *addr; 1.193 + ULONG status, size; 1.194 + int index = 0; 1.195 + 1.196 + if (!ifname) { 1.197 + return 0; 1.198 + } 1.199 + 1.200 + size = 0; 1.201 + status = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size); 1.202 + if (status != ERROR_BUFFER_OVERFLOW) { 1.203 + return 0; 1.204 + } 1.205 + addresses = malloc(size); 1.206 + status = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &size); 1.207 + if (status == ERROR_SUCCESS) { 1.208 + for (addr = addresses; addr; addr = addr->Next) { 1.209 + if (addr->AdapterName && !strcmp(ifname, addr->AdapterName)) { 1.210 + index = addr->IfIndex; 1.211 + break; 1.212 + } 1.213 + } 1.214 + } 1.215 + 1.216 + free(addresses); 1.217 + return index; 1.218 +} 1.219 + 1.220 +#if WINVER < 0x0600 1.221 +/* These functions are written based on the code at 1.222 + * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html 1.223 + * Therefore, for the rest of the file the following applies: 1.224 + * 1.225 + * 1.226 + * Copyright and Licensing Information for ACE(TM), TAO(TM), CIAO(TM), 1.227 + * DAnCE(TM), and CoSMIC(TM) 1.228 + * 1.229 + * [1]ACE(TM), [2]TAO(TM), [3]CIAO(TM), DAnCE(TM), and [4]CoSMIC(TM) 1.230 + * (henceforth referred to as "DOC software") are copyrighted by 1.231 + * [5]Douglas C. Schmidt and his [6]research group at [7]Washington 1.232 + * University, [8]University of California, Irvine, and [9]Vanderbilt 1.233 + * University, Copyright (c) 1993-2012, all rights reserved. Since DOC 1.234 + * software is open-source, freely available software, you are free to 1.235 + * use, modify, copy, and distribute--perpetually and irrevocably--the 1.236 + * DOC software source code and object code produced from the source, as 1.237 + * well as copy and distribute modified versions of this software. You 1.238 + * must, however, include this copyright statement along with any code 1.239 + * built using DOC software that you release. No copyright statement 1.240 + * needs to be provided if you just ship binary executables of your 1.241 + * software products. 1.242 + * 1.243 + * You can use DOC software in commercial and/or binary software releases 1.244 + * and are under no obligation to redistribute any of your source code 1.245 + * that is built using DOC software. Note, however, that you may not 1.246 + * misappropriate the DOC software code, such as copyrighting it yourself 1.247 + * or claiming authorship of the DOC software code, in a way that will 1.248 + * prevent DOC software from being distributed freely using an 1.249 + * open-source development model. You needn't inform anyone that you're 1.250 + * using DOC software in your software, though we encourage you to let 1.251 + * [10]us know so we can promote your project in the [11]DOC software 1.252 + * success stories. 1.253 + * 1.254 + * The [12]ACE, [13]TAO, [14]CIAO, [15]DAnCE, and [16]CoSMIC web sites 1.255 + * are maintained by the [17]DOC Group at the [18]Institute for Software 1.256 + * Integrated Systems (ISIS) and the [19]Center for Distributed Object 1.257 + * Computing of Washington University, St. Louis for the development of 1.258 + * open-source software as part of the open-source software community. 1.259 + * Submissions are provided by the submitter ``as is'' with no warranties 1.260 + * whatsoever, including any warranty of merchantability, noninfringement 1.261 + * of third party intellectual property, or fitness for any particular 1.262 + * purpose. In no event shall the submitter be liable for any direct, 1.263 + * indirect, special, exemplary, punitive, or consequential damages, 1.264 + * including without limitation, lost profits, even if advised of the 1.265 + * possibility of such damages. Likewise, DOC software is provided as is 1.266 + * with no warranties of any kind, including the warranties of design, 1.267 + * merchantability, and fitness for a particular purpose, 1.268 + * noninfringement, or arising from a course of dealing, usage or trade 1.269 + * practice. Washington University, UC Irvine, Vanderbilt University, 1.270 + * their employees, and students shall have no liability with respect to 1.271 + * the infringement of copyrights, trade secrets or any patents by DOC 1.272 + * software or any part thereof. Moreover, in no event will Washington 1.273 + * University, UC Irvine, or Vanderbilt University, their employees, or 1.274 + * students be liable for any lost revenue or profits or other special, 1.275 + * indirect and consequential damages. 1.276 + * 1.277 + * DOC software is provided with no support and without any obligation on 1.278 + * the part of Washington University, UC Irvine, Vanderbilt University, 1.279 + * their employees, or students to assist in its use, correction, 1.280 + * modification, or enhancement. A [20]number of companies around the 1.281 + * world provide commercial support for DOC software, however. DOC 1.282 + * software is Y2K-compliant, as long as the underlying OS platform is 1.283 + * Y2K-compliant. Likewise, DOC software is compliant with the new US 1.284 + * daylight savings rule passed by Congress as "The Energy Policy Act of 1.285 + * 2005," which established new daylight savings times (DST) rules for 1.286 + * the United States that expand DST as of March 2007. Since DOC software 1.287 + * obtains time/date and calendaring information from operating systems 1.288 + * users will not be affected by the new DST rules as long as they 1.289 + * upgrade their operating systems accordingly. 1.290 + * 1.291 + * The names ACE(TM), TAO(TM), CIAO(TM), DAnCE(TM), CoSMIC(TM), 1.292 + * Washington University, UC Irvine, and Vanderbilt University, may not 1.293 + * be used to endorse or promote products or services derived from this 1.294 + * source without express written permission from Washington University, 1.295 + * UC Irvine, or Vanderbilt University. This license grants no permission 1.296 + * to call products or services derived from this source ACE(TM), 1.297 + * TAO(TM), CIAO(TM), DAnCE(TM), or CoSMIC(TM), nor does it grant 1.298 + * permission for the name Washington University, UC Irvine, or 1.299 + * Vanderbilt University to appear in their names. 1.300 + * 1.301 + * If you have any suggestions, additions, comments, or questions, please 1.302 + * let [21]me know. 1.303 + * 1.304 + * [22]Douglas C. Schmidt 1.305 + * 1.306 + * References 1.307 + * 1.308 + * 1. http://www.cs.wustl.edu/~schmidt/ACE.html 1.309 + * 2. http://www.cs.wustl.edu/~schmidt/TAO.html 1.310 + * 3. http://www.dre.vanderbilt.edu/CIAO/ 1.311 + * 4. http://www.dre.vanderbilt.edu/cosmic/ 1.312 + * 5. http://www.dre.vanderbilt.edu/~schmidt/ 1.313 + * 6. http://www.cs.wustl.edu/~schmidt/ACE-members.html 1.314 + * 7. http://www.wustl.edu/ 1.315 + * 8. http://www.uci.edu/ 1.316 + * 9. http://www.vanderbilt.edu/ 1.317 + * 10. mailto:doc_group@cs.wustl.edu 1.318 + * 11. http://www.cs.wustl.edu/~schmidt/ACE-users.html 1.319 + * 12. http://www.cs.wustl.edu/~schmidt/ACE.html 1.320 + * 13. http://www.cs.wustl.edu/~schmidt/TAO.html 1.321 + * 14. http://www.dre.vanderbilt.edu/CIAO/ 1.322 + * 15. http://www.dre.vanderbilt.edu/~schmidt/DOC_ROOT/DAnCE/ 1.323 + * 16. http://www.dre.vanderbilt.edu/cosmic/ 1.324 + * 17. http://www.dre.vanderbilt.edu/ 1.325 + * 18. http://www.isis.vanderbilt.edu/ 1.326 + * 19. http://www.cs.wustl.edu/~schmidt/doc-center.html 1.327 + * 20. http://www.cs.wustl.edu/~schmidt/commercial-support.html 1.328 + * 21. mailto:d.schmidt@vanderbilt.edu 1.329 + * 22. http://www.dre.vanderbilt.edu/~schmidt/ 1.330 + * 23. http://www.cs.wustl.edu/ACE.html 1.331 + */ 1.332 + 1.333 +void 1.334 +InitializeXPConditionVariable(userland_cond_t *cv) 1.335 +{ 1.336 + cv->waiters_count = 0; 1.337 + InitializeCriticalSection(&(cv->waiters_count_lock)); 1.338 + cv->events_[C_SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL); 1.339 + cv->events_[C_BROADCAST] = CreateEvent (NULL, TRUE, FALSE, NULL); 1.340 +} 1.341 + 1.342 +void 1.343 +DeleteXPConditionVariable(userland_cond_t *cv) 1.344 +{ 1.345 + CloseHandle(cv->events_[C_BROADCAST]); 1.346 + CloseHandle(cv->events_[C_SIGNAL]); 1.347 + DeleteCriticalSection(&(cv->waiters_count_lock)); 1.348 +} 1.349 + 1.350 +int 1.351 +SleepXPConditionVariable(userland_cond_t *cv, userland_mutex_t *mtx) 1.352 +{ 1.353 + int result, last_waiter; 1.354 + 1.355 + EnterCriticalSection(&cv->waiters_count_lock); 1.356 + cv->waiters_count++; 1.357 + LeaveCriticalSection(&cv->waiters_count_lock); 1.358 + LeaveCriticalSection (mtx); 1.359 + result = WaitForMultipleObjects(2, cv->events_, FALSE, INFINITE); 1.360 + if (result==-1) { 1.361 + result = GetLastError(); 1.362 + } 1.363 + EnterCriticalSection(&cv->waiters_count_lock); 1.364 + cv->waiters_count--; 1.365 + last_waiter = 1.366 + result == (C_SIGNAL + C_BROADCAST && (cv->waiters_count == 0)); 1.367 + LeaveCriticalSection(&cv->waiters_count_lock); 1.368 + if (last_waiter) 1.369 + ResetEvent(cv->events_[C_BROADCAST]); 1.370 + EnterCriticalSection (mtx); 1.371 + return result; 1.372 +} 1.373 + 1.374 +void 1.375 +WakeAllXPConditionVariable(userland_cond_t *cv) 1.376 +{ 1.377 + int have_waiters; 1.378 + EnterCriticalSection(&cv->waiters_count_lock); 1.379 + have_waiters = cv->waiters_count > 0; 1.380 + LeaveCriticalSection(&cv->waiters_count_lock); 1.381 + if (have_waiters) 1.382 + SetEvent (cv->events_[C_BROADCAST]); 1.383 +} 1.384 +#endif 1.385 +#endif