1 /*****************************************************************************
2 * winsock.c: POSIX replacements for Winsock
3 *****************************************************************************
4 * Copyright © 2006-2008 Rémi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
25 #include <vlc_common.h>
27 #include <vlc_network.h>
29 #ifndef WSA_QOS_EUNKNOWNPSOBJ
30 # define WSA_QOS_EUNKNOWNPSOBJ 11024L
39 static const wsaerrmsg_t wsaerrmsg
[] =
41 { WSA_INVALID_HANDLE
, "Specified event object handle is invalid" },
42 { WSA_NOT_ENOUGH_MEMORY
, "Insufficient memory available" },
43 { WSA_INVALID_PARAMETER
, "One or more parameters are invalid" },
44 { WSA_OPERATION_ABORTED
, "Overlapped operation aborted" },
45 { WSA_IO_INCOMPLETE
, "Overlapped I/O event object not in signaled state" },
46 { WSA_IO_PENDING
, "Overlapped operations will complete later" },
47 { WSAEINTR
, "Interrupted function call" },
48 { WSAEBADF
, "File handle is not valid" },
49 { WSAEACCES
, "Access denied" },
50 { WSAEFAULT
, "Invalid memory address" },
51 { WSAEINVAL
, "Invalid argument" },
52 { WSAEMFILE
, "Too many open sockets" },
53 { WSAEWOULDBLOCK
, "Resource temporarily unavailable" },
54 { WSAEINPROGRESS
, "Operation now in progress" },
55 { WSAEALREADY
, "Operation already in progress" },
56 { WSAENOTSOCK
, "Non-socket handle specified" },
57 { WSAEDESTADDRREQ
, "Missing destination address" },
58 { WSAEMSGSIZE
, "Message too long" },
59 { WSAEPROTOTYPE
, "Protocol wrong type for socket", },
60 { WSAENOPROTOOPT
, "Option not supported by protocol" },
61 { WSAEPROTONOSUPPORT
, "Protocol not supported" },
62 { WSAESOCKTNOSUPPORT
, "Socket type not supported" },
63 { WSAEOPNOTSUPP
, "Operation not supported" },
64 { WSAEPFNOSUPPORT
, "Protocol family not supported" },
65 { WSAEAFNOSUPPORT
, "Address family not supported by protocol family" },
66 { WSAEADDRINUSE
, "Address already in use" },
67 { WSAEADDRNOTAVAIL
, "Cannot assign requested address" },
68 { WSAENETDOWN
, "Network is down" },
69 { WSAENETUNREACH
, "Network unreachable" },
70 { WSAENETRESET
, "Network dropped connection on reset" },
71 { WSAECONNABORTED
, "Software caused connection abort" },
72 { WSAECONNRESET
, "Connection reset by peer" },
73 { WSAENOBUFS
, "No buffer space available (not enough memory)" },
74 { WSAEISCONN
, "Socket is already connected" },
75 { WSAENOTCONN
, "Socket is not connected" },
76 { WSAESHUTDOWN
, "Cannot send after socket shutdown" },
77 { WSAETOOMANYREFS
, "Too many references" },
78 { WSAETIMEDOUT
, "Connection timed out" },
79 { WSAECONNREFUSED
, "Connection refused by peer" },
80 { WSAELOOP
, "Cannot translate name" },
81 { WSAENAMETOOLONG
, "Name too long" },
82 { WSAEHOSTDOWN
, "Remote host is down" },
83 { WSAEHOSTUNREACH
, "No route to host (unreachable)" },
84 { WSAENOTEMPTY
, "Directory not empty" },
85 { WSAEPROCLIM
, "Too many processes" },
86 { WSAEUSERS
, "User quota exceeded" },
87 { WSAEDQUOT
, "Disk quota exceeded" },
88 { WSAESTALE
, "Stale file handle reference" },
89 { WSAEREMOTE
, "Item is remote", },
90 { WSASYSNOTREADY
, "Network subsystem is unavailable (network stack not ready)" },
91 { WSAVERNOTSUPPORTED
, "Winsock.dll version out of range (network stack version not supported" },
92 { WSANOTINITIALISED
, "Network not initialized" },
93 { WSAEDISCON
, "Graceful shutdown in progress" },
94 { WSAENOMORE
, "No more results" },
95 { WSAECANCELLED
, "Call has been cancelled" },
96 { WSAEINVALIDPROCTABLE
, "Procedure call table is invalid" },
97 { WSAEINVALIDPROVIDER
, "Service provider is invalid" },
98 { WSAEPROVIDERFAILEDINIT
, "Service provider failed to initialize" },
99 { WSASYSCALLFAILURE
, "System call failure" },
100 { WSASERVICE_NOT_FOUND
, "Service not found" },
101 { WSATYPE_NOT_FOUND
, "Class type not found" },
102 { WSA_E_NO_MORE
, "No more results" },
103 { WSA_E_CANCELLED
, "Call was cancelled" },
104 { WSAEREFUSED
, "Database query was refused" },
105 { WSAHOST_NOT_FOUND
, "Host not found" },
106 { WSATRY_AGAIN
, "Nonauthoritative host not found (temporary hostname error)" },
107 { WSANO_RECOVERY
, "Non-recoverable hostname error" },
108 { WSANO_DATA
, "Valid name, no data record of requested type" },
109 { WSA_QOS_RECEIVERS
, "QOS receivers" },
110 { WSA_QOS_SENDERS
, "QOS senders" },
111 { WSA_QOS_NO_SENDERS
, "No QOS senders" },
112 { WSA_QOS_NO_RECEIVERS
, "QOS no receivers" },
113 { WSA_QOS_REQUEST_CONFIRMED
, "QOS request confirmed" },
114 { WSA_QOS_ADMISSION_FAILURE
, "QOS admission error" },
115 { WSA_QOS_POLICY_FAILURE
, "QOS policy failure" },
116 { WSA_QOS_BAD_STYLE
, "QOS bad style" },
117 { WSA_QOS_BAD_OBJECT
, "QOS bad object" },
118 { WSA_QOS_TRAFFIC_CTRL_ERROR
, "QOS traffic control error" },
119 { WSA_QOS_GENERIC_ERROR
, "QOS generic error" },
120 { WSA_QOS_ESERVICETYPE
, "QOS service type error" },
121 { WSA_QOS_EFLOWSPEC
, "QOS flowspec error" },
122 { WSA_QOS_EPROVSPECBUF
, "Invalid QOS provider buffer" },
123 { WSA_QOS_EFILTERSTYLE
, "Invalid QOS filter style" },
124 { WSA_QOS_EFILTERTYPE
, "Invalid QOS filter type" },
125 { WSA_QOS_EFILTERCOUNT
, "Incorrect QOS filter count" },
126 { WSA_QOS_EOBJLENGTH
, "Invalid QOS object length" },
127 { WSA_QOS_EFLOWCOUNT
, "Incorrect QOS flow count" },
128 { WSA_QOS_EUNKNOWNPSOBJ
, "Unrecognized QOS object" },
129 { WSA_QOS_EPOLICYOBJ
, "Invalid QOS policy object" },
130 { WSA_QOS_EFLOWDESC
, "Invalid QOS flow descriptor" },
131 { WSA_QOS_EPSFLOWSPEC
, "Invalid QOS provider-specific flowspec" },
132 { WSA_QOS_EPSFILTERSPEC
, "Invalid QOS provider-specific filterspec" },
133 { WSA_QOS_ESDMODEOBJ
, "Invalid QOS shape discard mode object" },
134 { WSA_QOS_ESHAPERATEOBJ
, "Invalid QOS shaping rate object" },
135 { WSA_QOS_RESERVED_PETYPE
, "Reserved policy QOS element type" },
137 /* Winsock2 error codes are missing, they "never" occur */
141 const char *net_strerror( int value
)
143 /* There doesn't seem to be any portable error message generation for
144 * Winsock errors. Some old versions had s_error, but it appears to be
145 * gone, and is not documented.
147 for( const wsaerrmsg_t
*e
= wsaerrmsg
; e
->msg
!= NULL
; e
++ )
148 if( e
->code
== value
)
151 /* Remember to update src/misc/messages.c if you change this one */
152 return "Unknown network stack error";
156 ssize_t
vlc_sendmsg (int s
, struct msghdr
*hdr
, int flags
)
158 /* WSASendMsg would be more straightforward, and would support ancilliary
159 * data, but it's not yet in mingw32. */
160 if ((hdr
->msg_iovlen
> 100) || (hdr
->msg_controllen
> 0))
166 WSABUF buf
[hdr
->msg_iovlen
];
167 for (size_t i
= 0; i
< sizeof (buf
) / sizeof (buf
[0]); i
++)
168 buf
[i
].buf
= hdr
->msg_iov
[i
].iov_base
,
169 buf
[i
].len
= hdr
->msg_iov
[i
].iov_len
;
172 if (WSASendTo (s
, buf
, sizeof (buf
) / sizeof (buf
[0]), &sent
, flags
,
173 hdr
->msg_name
, hdr
->msg_namelen
, NULL
, NULL
) == 0)
178 ssize_t
vlc_recvmsg (int s
, struct msghdr
*hdr
, int flags
)
180 /* WSARecvMsg would be more straightforward, and would support ancilliary
181 * data, but it's not yet in mingw32. */
182 if (hdr
->msg_iovlen
> 100)
188 WSABUF buf
[hdr
->msg_iovlen
];
189 for (size_t i
= 0; i
< sizeof (buf
) / sizeof (buf
[0]); i
++)
190 buf
[i
].buf
= hdr
->msg_iov
[i
].iov_base
,
191 buf
[i
].len
= hdr
->msg_iov
[i
].iov_len
;
193 DWORD recvd
, dwFlags
= flags
;
194 INT fromlen
= hdr
->msg_namelen
;
195 hdr
->msg_controllen
= 0;
198 int ret
= WSARecvFrom (s
, buf
, sizeof (buf
) / sizeof (buf
[0]), &recvd
,
199 &dwFlags
, hdr
->msg_name
, &fromlen
, NULL
, NULL
);
200 hdr
->msg_namelen
= fromlen
;
201 hdr
->msg_flags
= dwFlags
;
206 if (WSAGetLastError() == WSAEMSGSIZE
)
208 hdr
->msg_flags
|= MSG_TRUNC
;
212 # warning Out-of-date Winsock header files!