socket.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #include "squid.h"
10 #include "compat/socket.h"
11 #include "compat/wserrno.h"
12 
13 #if _SQUID_WINDOWS_ || _SQUID_MINGW_
14 #include <unordered_map>
15 
16 int
17 xaccept(int socketFd, struct sockaddr *sa, socklen_t *saLength)
18 {
19  const auto handle = _get_osfhandle(socketFd);
20  if (!isValidSocketHandle(handle)) {
21  // errno is already set by _get_osfhandle()
22  return SOCKET_ERROR;
23  }
24  int al = 0;
25  int *alp = nullptr;
26  if (saLength) {
27  assert(*saLength <= INT_MAX);
28  al = static_cast<int>(*saLength);
29  alp = &al;
30  }
31  const auto result = accept(handle, sa, alp);
32  if (result == INVALID_SOCKET) {
33  SetErrnoFromWsaError();
34  return SOCKET_ERROR;
35  }
36  const auto rv = _open_osfhandle(result, 0);
37  if (rv == -1) {
38  closesocket(result);
39  errno = EBADF;
40  }
41  if (saLength)
42  *saLength = static_cast<socklen_t>(al);
43  return rv;
44 }
45 
46 int
47 xbind(int socketFd, const struct sockaddr *sa, socklen_t saLength)
48 {
49  const auto handle = _get_osfhandle(socketFd);
50  if (!isValidSocketHandle(handle)) {
51  // errno is already set by _get_osfhandle()
52  return SOCKET_ERROR;
53  }
54  assert(saLength <= INT_MAX);
55  const auto result = bind(handle, sa, static_cast<int>(saLength));
56  if (result == SOCKET_ERROR)
57  SetErrnoFromWsaError();
58  return result;
59 }
60 
61 int
62 xconnect(int socketFd, const struct sockaddr *sa, socklen_t saLength)
63 {
64  const auto handle = _get_osfhandle(socketFd);
65  if (!isValidSocketHandle(handle)) {
66  // errno is already set by _get_osfhandle()
67  return SOCKET_ERROR;
68  }
69  assert(saLength <= INT_MAX);
70  const auto result = connect(handle, sa, static_cast<int>(saLength));
71  if (result == SOCKET_ERROR)
72  SetErrnoFromWsaError();
73  return result;
74 }
75 
76 int
77 xgetsockname(int socketFd, struct sockaddr * sa, socklen_t * saLength)
78 {
79  const auto handle = _get_osfhandle(socketFd);
80  if (!isValidSocketHandle(handle)) {
81  // errno is already set by _get_osfhandle()
82  return SOCKET_ERROR;
83  }
84  int al = 0;
85  int *alp = nullptr;
86  if (saLength) {
87  assert(*saLength <= INT_MAX);
88  al = static_cast<int>(*saLength);
89  alp = &al;
90  }
91  const auto result = getsockname(handle, sa, alp);
92  if (result == SOCKET_ERROR)
93  SetErrnoFromWsaError();
94  if (saLength)
95  *saLength = static_cast<socklen_t>(al);
96  return result;
97 }
98 
99 int
100 xgetsockopt(int socketFd, int level, int optionName, void * optionValue, socklen_t * optionLength)
101 {
102  const auto handle = _get_osfhandle(socketFd);
103  if (!isValidSocketHandle(handle)) {
104  // errno is already set by _get_osfhandle()
105  return SOCKET_ERROR;
106  }
107  int ol = 0;
108  int *olp = nullptr;
109  if (optionLength) {
110  assert(*optionLength <= INT_MAX);
111  ol = static_cast<int>(*optionLength);
112  olp = &ol;
113  }
114  const auto result = getsockopt(handle, level, optionName, static_cast<char *>(optionValue), olp);
115  if (result == SOCKET_ERROR)
116  SetErrnoFromWsaError();
117  if (optionLength)
118  *optionLength = static_cast<socklen_t>(ol);
119  return result;
120 }
121 
122 int
123 xlisten(int socketFd, int backlog)
124 {
125  const auto handle = _get_osfhandle(socketFd);
126  if (!isValidSocketHandle(handle)) {
127  // errno is already set by _get_osfhandle()
128  return SOCKET_ERROR;
129  }
130  const auto result = listen(handle, backlog);
131  if (result == SOCKET_ERROR)
132  SetErrnoFromWsaError();
133  return result;
134 }
135 
136 ssize_t
137 xrecv(int socketFd, void * buf, size_t bufLength, int flags)
138 {
139  const auto handle = _get_osfhandle(socketFd);
140  if (!isValidSocketHandle(handle)) {
141  // errno is already set by _get_osfhandle()
142  return SOCKET_ERROR;
143  }
144  assert(bufLength <= INT_MAX);
145  const auto result = recv(handle, static_cast<char *>(buf), static_cast<int>(bufLength), flags);
146  if (result == SOCKET_ERROR)
147  SetErrnoFromWsaError();
148  return result;
149 }
150 
151 ssize_t
152 xrecvfrom(int socketFd, void * buf, size_t bufLength, int flags, struct sockaddr * from, socklen_t * fromLength)
153 {
154  const auto handle = _get_osfhandle(socketFd);
155  if (!isValidSocketHandle(handle)) {
156  // errno is already set by _get_osfhandle()
157  return SOCKET_ERROR;
158  }
159  assert(bufLength <= INT_MAX);
160  int fl = 0;
161  int *flp = nullptr;
162  if (fromLength) {
163  assert(*fromLength <= INT_MAX);
164  fl = static_cast<int>(*fromLength);
165  flp = &fl;
166  }
167  const auto result = recvfrom(handle, static_cast<char *>(buf), static_cast<int>(bufLength), flags, from, flp);
168  if (result == SOCKET_ERROR)
169  SetErrnoFromWsaError();
170  if (fromLength)
171  *fromLength = static_cast<socklen_t>(fl);
172  return result;
173 }
174 
175 ssize_t
176 xsend(int socketFd, const void * buf, size_t bufLength, int flags)
177 {
178  const auto handle = _get_osfhandle(socketFd);
179  if (!isValidSocketHandle(handle)) {
180  // errno is already set by _get_osfhandle()
181  return SOCKET_ERROR;
182  }
183  assert(bufLength <= INT_MAX);
184  const auto result = send(handle, static_cast<const char *>(buf), static_cast<int>(bufLength), flags);
185  if (result == SOCKET_ERROR)
186  SetErrnoFromWsaError();
187  return result;
188 }
189 
190 ssize_t
191 xsendto(int socketFd, const void * buf, size_t bufLength, int flags, const struct sockaddr * to, socklen_t toLength)
192 {
193  const auto handle = _get_osfhandle(socketFd);
194  if (!isValidSocketHandle(handle)) {
195  // errno is already set by _get_osfhandle()
196  return SOCKET_ERROR;
197  }
198  assert(bufLength <= INT_MAX);
199  assert(toLength <= INT_MAX);
200  const auto result = sendto(handle, static_cast<const char *>(buf), static_cast<int>(bufLength), flags, to, static_cast<int>(toLength));
201  if (result == SOCKET_ERROR)
202  SetErrnoFromWsaError();
203  return result;
204 }
205 
206 int
207 xsetsockopt(int socketFd, int level, int option, const void *value, socklen_t valueLength)
208 {
209  const auto handle = _get_osfhandle(socketFd);
210  if (!isValidSocketHandle(handle)) {
211  // errno is already set by _get_osfhandle()
212  return SOCKET_ERROR;
213  }
214  assert(option <= INT_MAX);
215  const auto result = setsockopt(handle, level, option, static_cast<const char *>(value), static_cast<int>(valueLength));
216  if (result == SOCKET_ERROR)
217  SetErrnoFromWsaError();
218  return result;
219 }
220 
221 int
222 xsocket(int domain, int type, int protocol)
223 {
224  const auto result = socket(domain, type, protocol);
225  if (result == INVALID_SOCKET) {
226  SetErrnoFromWsaError();
227  return SOCKET_ERROR;
228  }
229  const auto rv = _open_osfhandle(result, 0);
230  if (rv == -1) {
231  closesocket(result);
232  errno = EBADF;
233  return SOCKET_ERROR;
234  }
235  return rv;
236 }
237 
238 #endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */
int xaccept(int socketFd, struct sockaddr *sa, socklen_t *saLength)
POSIX accept(2) equivalent.
Definition: socket.h:62
int socklen_t
Definition: types.h:137
ssize_t xsend(int socketFd, const void *buf, size_t bufLength, int flags)
POSIX send(2) equivalent.
Definition: socket.h:110
ssize_t xrecvfrom(int socketFd, void *buf, size_t bufLength, int flags, struct sockaddr *from, socklen_t *fromLength)
POSIX recvfrom(2) equivalent.
Definition: socket.h:104
int xgetsockname(int socketFd, struct sockaddr *sa, socklen_t *saLength)
POSIX getsockname(2) equivalent.
Definition: socket.h:80
#define INT_MAX
Definition: types.h:70
int xsetsockopt(int socketFd, int level, int option, const void *value, socklen_t valueLength)
POSIX setsockopt(2) equivalent.
Definition: socket.h:122
#define assert(EX)
Definition: assert.h:17
int xgetsockopt(int socketFd, int level, int optionName, void *optionValue, socklen_t *optionLength)
POSIX getsockopt(2) equivalent.
Definition: socket.h:92
int xsocket(int domain, int type, int protocol)
POSIX socket(2) equivalent.
Definition: socket.h:128
ssize_t xrecv(int socketFd, void *buf, size_t bufLength, int flags)
POSIX recv(2) equivalent.
Definition: socket.h:98
ssize_t xsendto(int socketFd, const void *buf, size_t bufLength, int flags, const struct sockaddr *to, socklen_t toLength)
POSIX sendto(2) equivalent.
Definition: socket.h:116
int xbind(int socketFd, const struct sockaddr *sa, socklen_t saLength)
POSIX bind(2) equivalent.
Definition: socket.h:68
int xconnect(int socketFd, const struct sockaddr *sa, socklen_t saLength)
POSIX connect(2) equivalent.
Definition: socket.h:74
int xlisten(int socketFd, int backlog)
POSIX listen(2) equivalent.
Definition: socket.h:86

 

Introduction

Documentation

Support

Miscellaneous