| ... | ... | @@ -1265,12 +1265,57 @@ fn netBindIp( |
| 1265 | 1265 | }; |
| 1266 | 1266 | } |
| 1267 | 1267 | fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Stream { |
| 1268 | if (options.timeout != .none) @panic("TODO"); |
| 1268 | 1269 | const k: *Kqueue = @ptrCast(@alignCast(userdata)); |
| 1269 | | _ = k; |
| 1270 | | _ = address; |
| 1271 | | _ = options; |
| 1272 | | @panic("TODO"); |
| 1270 | const family = Io.Threaded.posixAddressFamily(address); |
| 1271 | const socket_fd = try openSocketPosix(k, family, .{ |
| 1272 | .mode = options.mode, |
| 1273 | .protocol = options.protocol, |
| 1274 | }); |
| 1275 | errdefer posix.close(socket_fd); |
| 1276 | var storage: Io.Threaded.PosixAddress = undefined; |
| 1277 | var addr_len = Io.Threaded.addressToPosix(address, &storage); |
| 1278 | try posixConnect(k, socket_fd, &storage.any, addr_len); |
| 1279 | try posixGetSockName(k, socket_fd, &storage.any, &addr_len); |
| 1280 | return .{ .socket = .{ |
| 1281 | .handle = socket_fd, |
| 1282 | .address = Io.Threaded.addressFromPosix(&storage), |
| 1283 | } }; |
| 1273 | 1284 | } |
| 1285 | |
| 1286 | fn posixConnect(k: *Kqueue, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void { |
| 1287 | while (true) { |
| 1288 | try k.checkCancel(); |
| 1289 | switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) { |
| 1290 | .SUCCESS => return, |
| 1291 | .INTR => continue, |
| 1292 | .CANCELED => return error.Canceled, |
| 1293 | .AGAIN => @panic("TODO"), |
| 1294 | .INPROGRESS => return, // Due to TCP fast open, we find out possible error later. |
| 1295 | |
| 1296 | .ADDRNOTAVAIL => return error.AddressUnavailable, |
| 1297 | .AFNOSUPPORT => return error.AddressFamilyUnsupported, |
| 1298 | .ALREADY => return error.ConnectionPending, |
| 1299 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. |
| 1300 | .CONNREFUSED => return error.ConnectionRefused, |
| 1301 | .CONNRESET => return error.ConnectionResetByPeer, |
| 1302 | .FAULT => |err| return errnoBug(err), |
| 1303 | .ISCONN => |err| return errnoBug(err), |
| 1304 | .HOSTUNREACH => return error.HostUnreachable, |
| 1305 | .NETUNREACH => return error.NetworkUnreachable, |
| 1306 | .NOTSOCK => |err| return errnoBug(err), |
| 1307 | .PROTOTYPE => |err| return errnoBug(err), |
| 1308 | .TIMEDOUT => return error.Timeout, |
| 1309 | .CONNABORTED => |err| return errnoBug(err), |
| 1310 | .ACCES => return error.AccessDenied, |
| 1311 | .PERM => |err| return errnoBug(err), |
| 1312 | .NOENT => |err| return errnoBug(err), |
| 1313 | .NETDOWN => return error.NetworkDown, |
| 1314 | else => |err| return posix.unexpectedErrno(err), |
| 1315 | } |
| 1316 | } |
| 1317 | } |
| 1318 | |
| 1274 | 1319 | fn netListenUnix( |
| 1275 | 1320 | userdata: ?*anyopaque, |
| 1276 | 1321 | unix_address: *const net.UnixAddress, |
| ... | ... | @@ -1343,6 +1388,7 @@ fn netSendOne( |
| 1343 | 1388 | }, |
| 1344 | 1389 | .INTR => continue, |
| 1345 | 1390 | .CANCELED => return error.Canceled, |
| 1391 | .AGAIN => @panic("TODO register kevent"), |
| 1346 | 1392 | |
| 1347 | 1393 | .ACCES => return error.AccessDenied, |
| 1348 | 1394 | .ALREADY => return error.FastOpenAlreadyInProgress, |