| ... | ... | @@ -248,7 +248,7 @@ pub fn io(t: *Threaded) Io { |
| 248 | 248 | else => netAcceptPosix, |
| 249 | 249 | }, |
| 250 | 250 | .netBindIp = switch (builtin.os.tag) { |
| 251 | | .windows => @panic("TODO"), |
| 251 | .windows => netBindIpWindows, |
| 252 | 252 | else => netBindIpPosix, |
| 253 | 253 | }, |
| 254 | 254 | .netConnectIp = switch (builtin.os.tag) { |
| ... | ... | @@ -2828,7 +2828,7 @@ fn netListenIpWindows( |
| 2828 | 2828 | .EAFNOSUPPORT => return error.AddressFamilyUnsupported, |
| 2829 | 2829 | .EMFILE => return error.ProcessFdQuotaExceeded, |
| 2830 | 2830 | .ENOBUFS => return error.SystemResources, |
| 2831 | | .EPROTONOSUPPORT => return error.ProtocolUnsupportedBySystem, |
| 2831 | .EPROTONOSUPPORT => return error.ProtocolUnsupportedByAddressFamily, |
| 2832 | 2832 | else => |err| return windows.unexpectedWSAError(err), |
| 2833 | 2833 | } |
| 2834 | 2834 | }; |
| ... | ... | @@ -3176,6 +3176,86 @@ fn netBindIpPosix( |
| 3176 | 3176 | }; |
| 3177 | 3177 | } |
| 3178 | 3178 | |
| 3179 | fn netBindIpWindows( |
| 3180 | userdata: ?*anyopaque, |
| 3181 | address: *const IpAddress, |
| 3182 | options: IpAddress.BindOptions, |
| 3183 | ) IpAddress.BindError!net.Socket { |
| 3184 | if (!have_networking) return error.NetworkDown; |
| 3185 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 3186 | const family = posixAddressFamily(address); |
| 3187 | const mode = posixSocketMode(options.mode); |
| 3188 | const protocol = posixProtocol(options.protocol); |
| 3189 | const socket_handle = while (true) { |
| 3190 | try t.checkCancel(); |
| 3191 | const flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED | ws2_32.WSA_FLAG_NO_HANDLE_INHERIT; |
| 3192 | const rc = ws2_32.WSASocketW(family, @bitCast(mode), @bitCast(protocol), null, 0, flags); |
| 3193 | if (rc != ws2_32.INVALID_SOCKET) break rc; |
| 3194 | switch (ws2_32.WSAGetLastError()) { |
| 3195 | .EINTR => continue, |
| 3196 | .ECANCELLED, .E_CANCELLED => return error.Canceled, |
| 3197 | .NOTINITIALISED => { |
| 3198 | try initializeWsa(t); |
| 3199 | continue; |
| 3200 | }, |
| 3201 | .EAFNOSUPPORT => return error.AddressFamilyUnsupported, |
| 3202 | .EMFILE => return error.ProcessFdQuotaExceeded, |
| 3203 | .ENOBUFS => return error.SystemResources, |
| 3204 | .EPROTONOSUPPORT => return error.ProtocolUnsupportedByAddressFamily, |
| 3205 | else => |err| return windows.unexpectedWSAError(err), |
| 3206 | } |
| 3207 | }; |
| 3208 | errdefer closeSocketWindows(socket_handle); |
| 3209 | var storage: WsaAddress = undefined; |
| 3210 | var addr_len = addressToWsa(address, &storage); |
| 3211 | |
| 3212 | while (true) { |
| 3213 | try t.checkCancel(); |
| 3214 | const rc = ws2_32.bind(socket_handle, &storage.any, addr_len); |
| 3215 | if (rc != ws2_32.SOCKET_ERROR) break; |
| 3216 | switch (ws2_32.WSAGetLastError()) { |
| 3217 | .EINTR => continue, |
| 3218 | .ECANCELLED, .E_CANCELLED => return error.Canceled, |
| 3219 | .NOTINITIALISED => { |
| 3220 | try initializeWsa(t); |
| 3221 | continue; |
| 3222 | }, |
| 3223 | .EADDRINUSE => return error.AddressInUse, |
| 3224 | .EADDRNOTAVAIL => return error.AddressUnavailable, |
| 3225 | .ENOTSOCK => |err| return wsaErrorBug(err), |
| 3226 | .EFAULT => |err| return wsaErrorBug(err), |
| 3227 | .EINVAL => |err| return wsaErrorBug(err), |
| 3228 | .ENOBUFS => return error.SystemResources, |
| 3229 | .ENETDOWN => return error.NetworkDown, |
| 3230 | else => |err| return windows.unexpectedWSAError(err), |
| 3231 | } |
| 3232 | } |
| 3233 | |
| 3234 | while (true) { |
| 3235 | try t.checkCancel(); |
| 3236 | const rc = ws2_32.getsockname(socket_handle, &storage.any, &addr_len); |
| 3237 | if (rc != ws2_32.SOCKET_ERROR) break; |
| 3238 | switch (ws2_32.WSAGetLastError()) { |
| 3239 | .EINTR => continue, |
| 3240 | .ECANCELLED, .E_CANCELLED => return error.Canceled, |
| 3241 | .NOTINITIALISED => { |
| 3242 | try initializeWsa(t); |
| 3243 | continue; |
| 3244 | }, |
| 3245 | .ENETDOWN => return error.NetworkDown, |
| 3246 | .EFAULT => |err| return wsaErrorBug(err), |
| 3247 | .ENOTSOCK => |err| return wsaErrorBug(err), |
| 3248 | .EINVAL => |err| return wsaErrorBug(err), |
| 3249 | else => |err| return windows.unexpectedWSAError(err), |
| 3250 | } |
| 3251 | } |
| 3252 | |
| 3253 | return .{ |
| 3254 | .handle = socket_handle, |
| 3255 | .address = addressFromWsa(&storage), |
| 3256 | }; |
| 3257 | } |
| 3258 | |
| 3179 | 3259 | fn openSocketPosix( |
| 3180 | 3260 | t: *Threaded, |
| 3181 | 3261 | family: posix.sa_family_t, |