Changeset 72283 in vbox
- Timestamp:
- May 22, 2018 12:10:03 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/socket.c
r71984 r72283 173 173 174 174 175 int 176 sobind(PNATState pData, struct socket *so) 177 { 178 bool fSamePorts = !!(pData->i32AliasMode & PKT_ALIAS_SAME_PORTS); 175 /* 176 * Worker for sobind() below. 177 */ 178 static int 179 sobindto(struct socket *so, uint32_t addr, uint16_t port) 180 { 179 181 struct sockaddr_in self; 180 int opt;181 int binderr; 182 i nt ret;183 184 /* do we need to bind the socket to specific host address/port?*/185 if (pData->bindIP.s_addr == INADDR_ANY && !fSamePorts) 186 return 0; 187 188 opt = 1;189 setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));182 int status; 183 184 if (addr == INADDR_ANY && port == 0 && so->so_type != IPPROTO_UDP) 185 { 186 /* TCP sockets without constraints don't need to be bound */ 187 Log2(("NAT: sobind: %s guest %RTnaipv4:%d - nothing to do\n", 188 so->so_type == IPPROTO_UDP ? "udp" : "tcp", 189 so->so_laddr.s_addr, ntohs(so->so_lport))); 190 return 0; 191 } 190 192 191 193 RT_ZERO(self); … … 194 196 #endif 195 197 self.sin_family = AF_INET; 196 self.sin_addr = pData->bindIP; 197 self.sin_port = fSamePorts ? so->so_lport : 0; 198 199 Log2(("NAT: binding guest %RTnaipv4:%d to host %RTnaipv4:%d\n", 200 so->so_laddr.s_addr, ntohs(so->so_lport), 201 self.sin_addr.s_addr, ntohs(self.sin_port))); 202 203 ret = bind(so->s, (struct sockaddr *)&self, sizeof(self)); 204 if (ret == 0) 205 { 206 Log2(("NAT: ... bind ok\n")); 207 return 0; 208 } 209 210 if (self.sin_port != 0) 211 { 212 if (pData->bindIP.s_addr != INADDR_ANY) 213 { 214 Log2(("NAT: failed to bind to %RTnaipv4:%d (bindip,sameports)," 215 " retrying with random port\n", 216 self.sin_addr.s_addr, self.sin_port)); 217 218 /* 219 * don't try to guess why bind() failed, retry without 220 * requesting the same port port 221 */ 222 self.sin_port = 0; 223 224 ret = bind(so->s, (struct sockaddr *)&self, sizeof(self)); 225 if (ret == 0) /* bindIP ok (but port is not the same) */ 226 { 227 Log2(("NAT: ... bind ok (without sameports)\n")); 228 return 0; 229 } 230 } 231 else 232 { 233 Log2(("NAT: failed to bind to 0.0.0.0:%d (sameports)," 234 " ignoring sameports\n", 235 self.sin_port)); 236 237 /* it's ok if we failed to get the same port */ 238 return 0; 239 } 240 } 241 242 binderr = errno; 243 244 Log2(("NAT: failed to bind to %RTnaipv4 (bindip)\n", 245 self.sin_addr.s_addr)); 246 247 closesocket(so->s); 248 so->s = -1; 249 #ifdef RT_OS_WINDOWS 250 WSASetLastError(binderr); 251 #else 252 errno = binderr; 253 #endif 254 return -1; 198 self.sin_addr.s_addr = addr; 199 self.sin_port = port; 200 201 status = bind(so->s, (struct sockaddr *)&self, sizeof(self)); 202 if (status == 0) 203 { 204 Log2(("NAT: sobind: %s guest %RTnaipv4:%d to host %RTnaipv4:%d\n", 205 so->so_type == IPPROTO_UDP ? "udp" : "tcp", 206 so->so_laddr.s_addr, ntohs(so->so_lport), addr, ntohs(port))); 207 return 0; 208 } 209 210 Log2(("NAT: sobind: %s guest %RTnaipv4:%d to host %RTnaipv4:%d error %d%s\n", 211 so->so_type == IPPROTO_UDP ? "udp" : "tcp", 212 so->so_laddr.s_addr, ntohs(so->so_lport), 213 addr, ntohs(port), 214 errno, port ? " (will retry with random port)" : "")); 215 216 if (port) /* retry without */ 217 status = sobindto(so, addr, 0); 218 219 if (addr) 220 return status; 221 else 222 return 0; 223 } 224 225 226 /* 227 * Bind the socket to specific host address and/or port if necessary. 228 * We also always bind udp sockets to force the local port to be 229 * allocated and known in advance. 230 */ 231 int 232 sobind(PNATState pData, struct socket *so) 233 { 234 uint32_t addr = pData->bindIP.s_addr; /* may be INADDR_ANY */ 235 bool fSamePorts = !!(pData->i32AliasMode & PKT_ALIAS_SAME_PORTS); 236 uint16_t port; 237 int status; 238 239 if (fSamePorts) 240 { 241 int opt = 1; 242 setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); 243 port = so->so_lport; 244 } 245 else 246 { 247 port = 0; 248 } 249 250 status = sobindto(so, addr, port); 251 return status; 255 252 } 256 253
Note:
See TracChangeset
for help on using the changeset viewer.