## Summary
This PR implements support for `localAddress` and `localPort` options in
TCP connections, allowing users to bind outgoing connections to a
specific local IP address and port.
This addresses issue #6888 and implements Node.js-compatible behavior
for these options.
## Changes
### C Layer (uSockets)
- **`bsd.c`**: Modified `bsd_create_connect_socket()` to accept a
`local_addr` parameter and call `bind()` before `connect()` when a local
address is specified
- **`context.c`**: Updated `us_socket_context_connect()` and
`start_connections()` to parse and pass local address parameters through
the connection flow
- **`libusockets.h`**: Updated public API signatures to include
`local_host` and `local_port` parameters
- **`internal.h`**: Added `local_host` and `local_port` fields to
`us_connecting_socket_t` structure
- **`openssl.c`**: Updated SSL connection function to match the new
signature
### Zig Layer
- **`SocketContext.zig`**: Updated `connect()` method to accept and pass
through `local_host` and `local_port` parameters
- **`socket.zig`**: Modified `connectAnon()` to handle local address
binding, including IPv6 bracket removal and proper memory management
- **`Handlers.zig`**: Added `localAddress` and `localPort` fields to
`SocketConfig` and implemented parsing from JavaScript options
- **`Listener.zig`**: Updated connection structures to store and pass
local binding information
- **`socket.zig` (bun.js/api/bun)**: Modified `doConnect()` to extract
and pass local address options
- Updated all other call sites (HTTP, MySQL, PostgreSQL, Valkey) to pass
`null, 0` for backward compatibility
### JavaScript Layer
- **`net.ts`**: Enabled `localAddress` and `localPort` support by
passing these options to `doConnect()` and removing TODO comments
### Tests
- **`06888-localaddress.test.ts`**: Added comprehensive tests covering:
- IPv4 local address binding
- IPv4 local address and port binding
- IPv6 local address binding (loopback)
- Backward compatibility (connections without local address)
## Test Results
All tests pass successfully:
```
✓ TCP socket can bind to localAddress - IPv4
✓ TCP socket can bind to localAddress and localPort - IPv4
✓ TCP socket can bind to localAddress - IPv6 loopback
✓ TCP socket without localAddress works normally
4 pass, 0 fail
```
## API Usage
```typescript
import net from "net";
// Connect with a specific local address
const client = net.createConnection({
host: "example.com",
port: 80,
localAddress: "192.168.1.100", // Bind to this local IP
localPort: 0, // Let system assign port (optional)
});
```
## Implementation Details
The implementation follows the same flow as Node.js:
1. JavaScript options are parsed in `Handlers.zig`
2. Local address/port are stored in the connection configuration
3. The Zig layer processes and passes them to the C layer
4. The C layer parses the local address and calls `bind()` before
`connect()`
5. Both IPv4 and IPv6 addresses are supported
Memory management is handled properly throughout the stack, with
appropriate allocation/deallocation at each layer.
Closes#6888🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>