mirror of
https://github.com/ziglang/zig.git
synced 2025-12-18 20:23:07 +00:00
x/net: generalize tcp.Address into ip.Address
Generalize `tcp.Address` into `ip.Address` given that multiple transport protocols apart from TCP (i.e. UDP) operate solely over IP.
This commit is contained in:
parent
cc6714a929
commit
5c4fbc4014
@ -12,6 +12,7 @@ pub const os = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const net = struct {
|
pub const net = struct {
|
||||||
|
pub const ip = @import("x/net/ip.zig");
|
||||||
pub const tcp = @import("x/net/tcp.zig");
|
pub const tcp = @import("x/net/tcp.zig");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
52
lib/std/x/net/ip.zig
Normal file
52
lib/std/x/net/ip.zig
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
const std = @import("../../std.zig");
|
||||||
|
|
||||||
|
const IPv4 = std.x.os.IPv4;
|
||||||
|
const IPv6 = std.x.os.IPv6;
|
||||||
|
const Socket = std.x.os.Socket;
|
||||||
|
|
||||||
|
const ip = @This();
|
||||||
|
|
||||||
|
/// A union of all eligible types of IP addresses.
|
||||||
|
pub const Address = union(enum) {
|
||||||
|
ipv4: IPv4.Address,
|
||||||
|
ipv6: IPv6.Address,
|
||||||
|
|
||||||
|
/// Instantiate a new address with a IPv4 host and port.
|
||||||
|
pub fn initIPv4(host: IPv4, port: u16) Address {
|
||||||
|
return .{ .ipv4 = .{ .host = host, .port = port } };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Instantiate a new address with a IPv6 host and port.
|
||||||
|
pub fn initIPv6(host: IPv6, port: u16) Address {
|
||||||
|
return .{ .ipv6 = .{ .host = host, .port = port } };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Re-interpret a generic socket address into an IP address.
|
||||||
|
pub fn from(address: Socket.Address) ip.Address {
|
||||||
|
return switch (address) {
|
||||||
|
.ipv4 => |ipv4_address| .{ .ipv4 = ipv4_address },
|
||||||
|
.ipv6 => |ipv6_address| .{ .ipv6 = ipv6_address },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Re-interpret an IP address into a generic socket address.
|
||||||
|
pub fn into(self: ip.Address) Socket.Address {
|
||||||
|
return switch (self) {
|
||||||
|
.ipv4 => |ipv4_address| .{ .ipv4 = ipv4_address },
|
||||||
|
.ipv6 => |ipv6_address| .{ .ipv6 = ipv6_address },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implements the `std.fmt.format` API.
|
||||||
|
pub fn format(
|
||||||
|
self: ip.Address,
|
||||||
|
comptime layout: []const u8,
|
||||||
|
opts: fmt.FormatOptions,
|
||||||
|
writer: anytype,
|
||||||
|
) !void {
|
||||||
|
switch (self) {
|
||||||
|
.ipv4 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
|
||||||
|
.ipv6 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -7,6 +7,8 @@
|
|||||||
const std = @import("../../std.zig");
|
const std = @import("../../std.zig");
|
||||||
|
|
||||||
const os = std.os;
|
const os = std.os;
|
||||||
|
const ip = std.x.net.ip;
|
||||||
|
|
||||||
const fmt = std.fmt;
|
const fmt = std.fmt;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const builtin = std.builtin;
|
const builtin = std.builtin;
|
||||||
@ -19,61 +21,16 @@ const Socket = std.x.os.Socket;
|
|||||||
/// A generic TCP socket abstraction.
|
/// A generic TCP socket abstraction.
|
||||||
const tcp = @This();
|
const tcp = @This();
|
||||||
|
|
||||||
/// A union of all eligible types of socket addresses over TCP.
|
|
||||||
pub const Address = union(enum) {
|
|
||||||
ipv4: IPv4.Address,
|
|
||||||
ipv6: IPv6.Address,
|
|
||||||
|
|
||||||
/// Instantiate a new address with a IPv4 host and port.
|
|
||||||
pub fn initIPv4(host: IPv4, port: u16) Address {
|
|
||||||
return .{ .ipv4 = .{ .host = host, .port = port } };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Instantiate a new address with a IPv6 host and port.
|
|
||||||
pub fn initIPv6(host: IPv6, port: u16) Address {
|
|
||||||
return .{ .ipv6 = .{ .host = host, .port = port } };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Re-interpret a generic socket address into a TCP socket address.
|
|
||||||
pub fn from(address: Socket.Address) tcp.Address {
|
|
||||||
return switch (address) {
|
|
||||||
.ipv4 => |ipv4_address| .{ .ipv4 = ipv4_address },
|
|
||||||
.ipv6 => |ipv6_address| .{ .ipv6 = ipv6_address },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Re-interpret a TCP socket address into a generic socket address.
|
|
||||||
pub fn into(self: tcp.Address) Socket.Address {
|
|
||||||
return switch (self) {
|
|
||||||
.ipv4 => |ipv4_address| .{ .ipv4 = ipv4_address },
|
|
||||||
.ipv6 => |ipv6_address| .{ .ipv6 = ipv6_address },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements the `std.fmt.format` API.
|
|
||||||
pub fn format(
|
|
||||||
self: tcp.Address,
|
|
||||||
comptime layout: []const u8,
|
|
||||||
opts: fmt.FormatOptions,
|
|
||||||
writer: anytype,
|
|
||||||
) !void {
|
|
||||||
switch (self) {
|
|
||||||
.ipv4 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
|
|
||||||
.ipv6 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A TCP client-address pair.
|
/// A TCP client-address pair.
|
||||||
pub const Connection = struct {
|
pub const Connection = struct {
|
||||||
client: tcp.Client,
|
client: tcp.Client,
|
||||||
address: tcp.Address,
|
address: ip.Address,
|
||||||
|
|
||||||
/// Enclose a TCP client and address into a client-address pair.
|
/// Enclose a TCP client and address into a client-address pair.
|
||||||
pub fn from(conn: Socket.Connection) tcp.Connection {
|
pub fn from(conn: Socket.Connection) tcp.Connection {
|
||||||
return .{
|
return .{
|
||||||
.client = tcp.Client.from(conn.socket),
|
.client = tcp.Client.from(conn.socket),
|
||||||
.address = tcp.Address.from(conn.address),
|
.address = ip.Address.from(conn.address),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +85,7 @@ pub const Client = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Have the client attempt to the connect to an address.
|
/// Have the client attempt to the connect to an address.
|
||||||
pub fn connect(self: Client, address: tcp.Address) !void {
|
pub fn connect(self: Client, address: ip.Address) !void {
|
||||||
return self.socket.connect(address.into());
|
return self.socket.connect(address.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,8 +142,8 @@ pub const Client = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Query the address that the client's socket is locally bounded to.
|
/// Query the address that the client's socket is locally bounded to.
|
||||||
pub fn getLocalAddress(self: Client) !tcp.Address {
|
pub fn getLocalAddress(self: Client) !ip.Address {
|
||||||
return tcp.Address.from(try self.socket.getLocalAddress());
|
return ip.Address.from(try self.socket.getLocalAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable Nagle's algorithm on a TCP socket. It returns `error.UnsupportedSocketOption` if
|
/// Disable Nagle's algorithm on a TCP socket. It returns `error.UnsupportedSocketOption` if
|
||||||
@ -253,7 +210,7 @@ pub const Listener = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Binds the listener's socket to an address.
|
/// Binds the listener's socket to an address.
|
||||||
pub fn bind(self: Listener, address: tcp.Address) !void {
|
pub fn bind(self: Listener, address: ip.Address) !void {
|
||||||
return self.socket.bind(address.into());
|
return self.socket.bind(address.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,8 +231,8 @@ pub const Listener = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Query the address that the listener's socket is locally bounded to.
|
/// Query the address that the listener's socket is locally bounded to.
|
||||||
pub fn getLocalAddress(self: Listener) !tcp.Address {
|
pub fn getLocalAddress(self: Listener) !ip.Address {
|
||||||
return tcp.Address.from(try self.socket.getLocalAddress());
|
return ip.Address.from(try self.socket.getLocalAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
|
/// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
|
||||||
@ -322,7 +279,7 @@ test "tcp: create client/listener pair" {
|
|||||||
const listener = try tcp.Listener.init(.ip, os.SOCK_CLOEXEC);
|
const listener = try tcp.Listener.init(.ip, os.SOCK_CLOEXEC);
|
||||||
defer listener.deinit();
|
defer listener.deinit();
|
||||||
|
|
||||||
try listener.bind(tcp.Address.initIPv4(IPv4.unspecified, 0));
|
try listener.bind(ip.Address.initIPv4(IPv4.unspecified, 0));
|
||||||
try listener.listen(128);
|
try listener.listen(128);
|
||||||
|
|
||||||
const binded_address = try listener.getLocalAddress();
|
const binded_address = try listener.getLocalAddress();
|
||||||
@ -342,7 +299,7 @@ test "tcp/client: set read timeout of 1 millisecond on blocking client" {
|
|||||||
const listener = try tcp.Listener.init(.ip, os.SOCK_CLOEXEC);
|
const listener = try tcp.Listener.init(.ip, os.SOCK_CLOEXEC);
|
||||||
defer listener.deinit();
|
defer listener.deinit();
|
||||||
|
|
||||||
try listener.bind(tcp.Address.initIPv4(IPv4.unspecified, 0));
|
try listener.bind(ip.Address.initIPv4(IPv4.unspecified, 0));
|
||||||
try listener.listen(128);
|
try listener.listen(128);
|
||||||
|
|
||||||
const binded_address = try listener.getLocalAddress();
|
const binded_address = try listener.getLocalAddress();
|
||||||
@ -366,7 +323,7 @@ test "tcp/listener: bind to unspecified ipv4 address" {
|
|||||||
const listener = try tcp.Listener.init(.ip, os.SOCK_CLOEXEC);
|
const listener = try tcp.Listener.init(.ip, os.SOCK_CLOEXEC);
|
||||||
defer listener.deinit();
|
defer listener.deinit();
|
||||||
|
|
||||||
try listener.bind(tcp.Address.initIPv4(IPv4.unspecified, 0));
|
try listener.bind(ip.Address.initIPv4(IPv4.unspecified, 0));
|
||||||
try listener.listen(128);
|
try listener.listen(128);
|
||||||
|
|
||||||
const address = try listener.getLocalAddress();
|
const address = try listener.getLocalAddress();
|
||||||
@ -379,7 +336,7 @@ test "tcp/listener: bind to unspecified ipv6 address" {
|
|||||||
const listener = try tcp.Listener.init(.ipv6, os.SOCK_CLOEXEC);
|
const listener = try tcp.Listener.init(.ipv6, os.SOCK_CLOEXEC);
|
||||||
defer listener.deinit();
|
defer listener.deinit();
|
||||||
|
|
||||||
try listener.bind(tcp.Address.initIPv6(IPv6.unspecified, 0));
|
try listener.bind(ip.Address.initIPv6(IPv6.unspecified, 0));
|
||||||
try listener.listen(128);
|
try listener.listen(128);
|
||||||
|
|
||||||
const address = try listener.getLocalAddress();
|
const address = try listener.getLocalAddress();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user