upd5
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
# Networking Library for V
|
# Networking Library for V
|
||||||
|
|
||||||
**netio** is a flexible networking library for V programming language.
|
`netio` is a flexible networking library for V programming language.
|
||||||
|
|
||||||
Differences with the V standard library `net` module:
|
Differences with the V standard library `net` module:
|
||||||
|
|
||||||
* Provides the low-level wrappers around C API.
|
* Provides the low-level wrappers around C API.
|
||||||
* Supports any kind of sockets, socket options, address families and protocols.
|
* Supports any kind of sockets, socket options, address families and protocols.
|
||||||
|
|
||||||
|
The `netio.protocol` module provides access to the operatins system protocols database.
|
||||||
|
|||||||
@@ -26,30 +26,30 @@ pub struct AddrInfo {
|
|||||||
pub:
|
pub:
|
||||||
flags AddrInfoFlag
|
flags AddrInfoFlag
|
||||||
family AddrFamily
|
family AddrFamily
|
||||||
sock_type SocketType
|
socktype SocketType
|
||||||
protocol Protocol
|
protocol Protocol
|
||||||
addr SocketAddr
|
addr SocketAddr
|
||||||
canonical string
|
canonical string
|
||||||
}
|
}
|
||||||
|
|
||||||
@[params]
|
@[params]
|
||||||
pub struct TranslateAddrParams {
|
pub struct AddrInfoParams {
|
||||||
pub:
|
pub:
|
||||||
node ?string
|
node ?string
|
||||||
service ?string
|
service ?string
|
||||||
family AddrFamily = af_unspec
|
family AddrFamily = af_unspec
|
||||||
sock_type SocketType
|
socktype SocketType
|
||||||
protocol Protocol
|
protocol Protocol
|
||||||
flags AddrInfoFlag
|
flags AddrInfoFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate_addr translates the network address. This is a low-level wrapper around
|
// addr_info translates the network addresses and services. This is a low-level wrapper around
|
||||||
// the [getaddrinfo(3)](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html) C API.
|
// the [getaddrinfo(3)](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html) C API.
|
||||||
pub fn translate_addr(hints TranslateAddrParams) ![]AddrInfo {
|
pub fn addr_info(hints AddrInfoParams) ![]AddrInfo {
|
||||||
mut hints_ := C.addrinfo{}
|
mut hints_ := C.addrinfo{}
|
||||||
unsafe { vmemset(&hints_, 0, int(sizeof(hints_))) }
|
unsafe { vmemset(&hints_, 0, int(sizeof(hints_))) }
|
||||||
hints_.ai_family = i32(hints.family)
|
hints_.ai_family = i32(hints.family)
|
||||||
hints_.ai_socktype = i32(hints.sock_type)
|
hints_.ai_socktype = i32(hints.socktype)
|
||||||
hints_.ai_protocol = i32(hints.protocol)
|
hints_.ai_protocol = i32(hints.protocol)
|
||||||
hints_.ai_flags = i32(hints.flags)
|
hints_.ai_flags = i32(hints.flags)
|
||||||
mut node := unsafe { nil }
|
mut node := unsafe { nil }
|
||||||
@@ -77,7 +77,7 @@ pub fn translate_addr(hints TranslateAddrParams) ![]AddrInfo {
|
|||||||
addrs << AddrInfo{
|
addrs << AddrInfo{
|
||||||
flags: int(result.ai_flags)
|
flags: int(result.ai_flags)
|
||||||
family: int(result.ai_family)
|
family: int(result.ai_family)
|
||||||
sock_type: int(result.ai_socktype)
|
socktype: int(result.ai_socktype)
|
||||||
protocol: int(result.ai_protocol)
|
protocol: int(result.ai_protocol)
|
||||||
addr: unsafe { SocketAddr.from_ptr(result.ai_addr, result.ai_addrlen)! }
|
addr: unsafe { SocketAddr.from_ptr(result.ai_addr, result.ai_addrlen)! }
|
||||||
canonical: if isnil(result.ai_canonname) {
|
canonical: if isnil(result.ai_canonname) {
|
||||||
@@ -93,14 +93,14 @@ pub fn translate_addr(hints TranslateAddrParams) ![]AddrInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@[params]
|
@[params]
|
||||||
pub struct TranslateNameParams {
|
pub struct NameInfoParams {
|
||||||
pub:
|
pub:
|
||||||
flags NameInfoFlag
|
flags NameInfoFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate_name does address-to-name translation and returns the host and service names.
|
// name_info does address-to-name translation and returns the host and service names.
|
||||||
// See [getnameinfo(3)](https://man7.org/linux/man-pages/man3/getnameinfo.3.html) for details.
|
// See [getnameinfo(3)](https://man7.org/linux/man-pages/man3/getnameinfo.3.html) for details.
|
||||||
pub fn translate_name(sa SocketAddr, params TranslateNameParams) !(string, string) {
|
pub fn name_info(sa SocketAddr, params NameInfoParams) !(string, string) {
|
||||||
mut addr := []u8{len: C.NI_MAXHOST}
|
mut addr := []u8{len: C.NI_MAXHOST}
|
||||||
mut serv := []u8{len: C.NI_MAXSERV}
|
mut serv := []u8{len: C.NI_MAXSERV}
|
||||||
code := C.getnameinfo(sa.ptr(), sa.size(), addr.data, addr.len, serv.data, serv.len,
|
code := C.getnameinfo(sa.ptr(), sa.size(), addr.data, addr.len, serv.data, serv.len,
|
||||||
@@ -5,7 +5,7 @@ fn main() {
|
|||||||
// Resolve the fully qualified domain name for host.
|
// Resolve the fully qualified domain name for host.
|
||||||
// This programm is analog for `hostname -f` command.
|
// This programm is analog for `hostname -f` command.
|
||||||
hostname := os.hostname()!
|
hostname := os.hostname()!
|
||||||
ai := netio.translate_addr(node: hostname, flags: netio.ai_canonname)!
|
ai := netio.addr_info(node: hostname, flags: netio.ai_canonname)!
|
||||||
mut fqdn := ''
|
mut fqdn := ''
|
||||||
for a in ai {
|
for a in ai {
|
||||||
// Not needed to iterate over all entries, return the first one per getaddrinfo(3).
|
// Not needed to iterate over all entries, return the first one per getaddrinfo(3).
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ fn main() {
|
|||||||
// Create new TCP socket.
|
// Create new TCP socket.
|
||||||
mut socket := netio.Socket.new(netio.af_inet, netio.sock_stream, 0)!
|
mut socket := netio.Socket.new(netio.af_inet, netio.sock_stream, 0)!
|
||||||
|
|
||||||
|
// Close socket on exit.
|
||||||
defer {
|
defer {
|
||||||
socket.close() or { panic(err) }
|
socket.close() or { panic(err) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the server socket address.
|
// Create the server socket address.
|
||||||
server_addr := netio.SocketAddr.ipv4([u8(127), 0, 0, 1]!, 1081)
|
server_addr := netio.SocketAddr.new_ipv4([u8(127), 0, 0, 1]!, 1081)
|
||||||
|
|
||||||
// Connect socket to the server address.
|
// Connect socket to the server address.
|
||||||
socket.connect(server_addr) or {
|
socket.connect(server_addr) or {
|
||||||
@@ -22,7 +23,10 @@ fn main() {
|
|||||||
// Send message to the server.
|
// Send message to the server.
|
||||||
msg := 'Hello from client!'
|
msg := 'Hello from client!'
|
||||||
|
|
||||||
sent := socket.send(msg.bytes(), 0)!
|
sent := socket.send(msg.bytes(), 0) or {
|
||||||
|
eprintln('SEND: ${err}')
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
eprintln('Sent to the server: ${sent} bytes, data: ${msg}')
|
eprintln('Sent to the server: ${sent} bytes, data: ${msg}')
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import netio
|
|||||||
fn main() {
|
fn main() {
|
||||||
// We want to bind a server socket to the all available local addresses,
|
// We want to bind a server socket to the all available local addresses,
|
||||||
// (both IPv4 and IPv6) so collect the address info entries for it.
|
// (both IPv4 and IPv6) so collect the address info entries for it.
|
||||||
ai := netio.translate_addr(
|
ai := netio.addr_info(
|
||||||
service: '1081' // The port number for listen.
|
service: '1081' // The port number to listen.
|
||||||
sock_type: netio.sock_stream // Address must support TCP transport.
|
socktype: netio.sock_stream // Address must support TCP transport.
|
||||||
family: netio.af_inet6 // IPv6 support.
|
family: netio.af_inet6 // IPv6 support.
|
||||||
flags: netio.ai_passive // Passive mode for binding to any address (0.0.0.0, ::).
|
flags: netio.ai_passive // Passive mode for binding to any address (0.0.0.0, ::).
|
||||||
)!
|
)!
|
||||||
|
|
||||||
// Just initialize variables.
|
// Just initialize variables.
|
||||||
@@ -17,7 +17,7 @@ fn main() {
|
|||||||
// Create socket and bind to the first available address.
|
// Create socket and bind to the first available address.
|
||||||
for a in ai {
|
for a in ai {
|
||||||
// Create a socket with advertised parameters.
|
// Create a socket with advertised parameters.
|
||||||
socket = netio.Socket.new(a.family, a.sock_type, a.protocol)!
|
socket = netio.Socket.new(a.family, a.socktype, a.protocol)!
|
||||||
|
|
||||||
// Set SO_REUSEADDR enabled. It allows a server to bind to a port that
|
// Set SO_REUSEADDR enabled. It allows a server to bind to a port that
|
||||||
// is still in a `TIME-WAIT` state from a previous connection.
|
// is still in a `TIME-WAIT` state from a previous connection.
|
||||||
@@ -49,6 +49,7 @@ fn main() {
|
|||||||
defer {
|
defer {
|
||||||
socket.close() or { panic(err) }
|
socket.close() or { panic(err) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start listening for incoming connections on socket.
|
// Start listening for incoming connections on socket.
|
||||||
socket.listen(10) or {
|
socket.listen(10) or {
|
||||||
eprintln('LISTEN: ${err}')
|
eprintln('LISTEN: ${err}')
|
||||||
@@ -70,7 +71,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get remote host and port in numeric format.
|
// Get remote host and port in numeric format.
|
||||||
remote_host, remote_port := netio.translate_name(remote_addr,
|
remote_host, remote_port := netio.name_info(remote_addr,
|
||||||
flags: netio.ni_numerichost | netio.ni_numericserv
|
flags: netio.ni_numerichost | netio.ni_numericserv
|
||||||
)!
|
)!
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
module netio
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
struct C.if_nameindex {
|
||||||
|
if_index u32
|
||||||
|
if_name &char
|
||||||
|
}
|
||||||
|
|
||||||
|
fn C.if_nametoindex(&char) u32
|
||||||
|
fn C.if_indextoname(u32, &char) &char
|
||||||
|
fn C.if_nameindex() &C.if_nameindex
|
||||||
|
fn C.if_freenameindex(voidptr)
|
||||||
|
|
||||||
|
// name_to_index translates the network interface name to index.
|
||||||
|
pub fn name_to_index(name string) !u32 {
|
||||||
|
index := C.if_nametoindex(&char(name.str))
|
||||||
|
if index == 0 {
|
||||||
|
return error('${@FN}: no index for `${name}`')
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
// index_to_name translates the network interface index to name e.g. 'eth0'.
|
||||||
|
pub fn index_to_name(index u32) !string {
|
||||||
|
name := []u8{len: C.IF_NAMESIZE}
|
||||||
|
ifname := C.if_indextoname(index, name.data)
|
||||||
|
if isnil(ifname) {
|
||||||
|
return os.last_error()
|
||||||
|
}
|
||||||
|
return unsafe { cstring_to_vstring(ifname) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NetworkInterface {
|
||||||
|
index u32
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// interfaces returns an array with names and indexes of all network interfaces in system.
|
||||||
|
pub fn interfaces() ![]NetworkInterface {
|
||||||
|
ifaces := C.if_nameindex()
|
||||||
|
if isnil(ifaces) {
|
||||||
|
return os.last_error()
|
||||||
|
}
|
||||||
|
defer {
|
||||||
|
C.if_freenameindex(ifaces)
|
||||||
|
}
|
||||||
|
mut result := []NetworkInterface{}
|
||||||
|
mut i := 0
|
||||||
|
for {
|
||||||
|
iface := unsafe { ifaces[i] }
|
||||||
|
i++
|
||||||
|
if iface.if_index == 0 && isnil(iface.if_name) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
result << NetworkInterface{
|
||||||
|
index: iface.if_index
|
||||||
|
name: unsafe { cstring_to_vstring(iface.if_name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import netio
|
||||||
|
|
||||||
|
fn test_interfaces() {
|
||||||
|
ifs := netio.interfaces()!
|
||||||
|
dump(ifs)
|
||||||
|
assert ifs.len > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_name_to_index() {
|
||||||
|
assert netio.name_to_index('lo')! == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_index_to_name() {
|
||||||
|
assert netio.index_to_name(1)! == 'lo'
|
||||||
|
}
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
# Protocols Database
|
# Protocols Database Access
|
||||||
|
|
||||||
The **protocol** module provides thread-safe access to the operatins system protocols database.
|
The `protocol` module provides thread-safe access to the operatins system protocols database.
|
||||||
|
|
||||||
See [protocols(5)](https://www.man7.org/linux/man-pages/man5/protocols.5.html)
|
See [protocols(5)](https://www.man7.org/linux/man-pages/man5/protocols.5.html)
|
||||||
and [getprotoent(3)](https://man7.org/linux/man-pages/man3/getprotoent.3.html)
|
and [getprotoent(3)](https://man7.org/linux/man-pages/man3/getprotoent.3.html)
|
||||||
|
|||||||
+2
-2
@@ -37,8 +37,8 @@ pub fn Socket.new(domain AddrFamily, st SocketType, proto Protocol) !Socket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// type_of reports the actual socket type.
|
// type reports the actual socket type.
|
||||||
pub fn (s Socket) type_of() !SocketType {
|
pub fn (s Socket) type() !SocketType {
|
||||||
return s.get_option_int(C.SOL_SOCKET, C.SO_TYPE)!
|
return s.get_option_int(C.SOL_SOCKET, C.SO_TYPE)!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-21
@@ -4,8 +4,7 @@ import encoding.binary
|
|||||||
|
|
||||||
struct C.sockaddr_storage {}
|
struct C.sockaddr_storage {}
|
||||||
|
|
||||||
// max_unix_path_size value is used to pad the sockaddr_un struct.
|
pub const max_unix_path_len = $if linux {
|
||||||
const max_unix_path_size = $if linux {
|
|
||||||
108
|
108
|
||||||
} $else $if windows {
|
} $else $if windows {
|
||||||
108
|
108
|
||||||
@@ -20,9 +19,9 @@ mut:
|
|||||||
pos int
|
pos int
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketAddr.ipv4 creates new AF_INET socket address.
|
// SocketAddr.new_ipv4 creates new AF_INET socket address.
|
||||||
// addr must be set in network (big-endian) byte order.
|
// addr must be set in network (big-endian) byte order.
|
||||||
pub fn SocketAddr.ipv4(addr [4]u8, port u16) SocketAddr {
|
pub fn SocketAddr.new_ipv4(addr [4]u8, port u16) SocketAddr {
|
||||||
mut sock_addr := unsafe { SocketAddr.new(af_inet, 16) }
|
mut sock_addr := unsafe { SocketAddr.new(af_inet, 16) }
|
||||||
unsafe {
|
unsafe {
|
||||||
sock_addr.push(binary.big_endian_get_u16(port)) or {}
|
sock_addr.push(binary.big_endian_get_u16(port)) or {}
|
||||||
@@ -31,10 +30,10 @@ pub fn SocketAddr.ipv4(addr [4]u8, port u16) SocketAddr {
|
|||||||
return sock_addr
|
return sock_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketAddr.ipv6 creates new AF_INET6 socket address.
|
// SocketAddr.new_ipv6 creates new AF_INET6 socket address.
|
||||||
// addr must be set in network (big-endian) byte order.
|
// addr must be set in network (big-endian) byte order.
|
||||||
// Use if_nametoindex(3) to get an integer scope_id from its string representation.
|
// Use if_nametoindex(3) to get an integer scope_id from its string representation.
|
||||||
pub fn SocketAddr.ipv6(addr [16]u8, port u16, flow_info u32, scope_id u32) SocketAddr {
|
pub fn SocketAddr.new_ipv6(addr [16]u8, port u16, flow_info u32, scope_id u32) SocketAddr {
|
||||||
mut sock_addr := unsafe { SocketAddr.new(af_inet6, 28) }
|
mut sock_addr := unsafe { SocketAddr.new(af_inet6, 28) }
|
||||||
unsafe {
|
unsafe {
|
||||||
sock_addr.push(binary.big_endian_get_u16(port)) or {}
|
sock_addr.push(binary.big_endian_get_u16(port)) or {}
|
||||||
@@ -45,12 +44,13 @@ pub fn SocketAddr.ipv6(addr [16]u8, port u16, flow_info u32, scope_id u32) Socke
|
|||||||
return sock_addr
|
return sock_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketAddr.unix creates new AF_UNIX socket address.
|
// SocketAddr.new_unix creates new AF_UNIX socket address with given path. The path must
|
||||||
pub fn SocketAddr.unix(path string) !SocketAddr {
|
// fit in platform dependent const `max_unix_path_len` value.
|
||||||
if path.len > max_unix_path_size {
|
pub fn SocketAddr.new_unix(path string) !SocketAddr {
|
||||||
|
if path.len > max_unix_path_len {
|
||||||
return error('Too long path to socket')
|
return error('Too long path to socket')
|
||||||
}
|
}
|
||||||
mut sock_addr := unsafe { SocketAddr.new(af_unix, usize(max_unix_path_size) + 2) }
|
mut sock_addr := unsafe { SocketAddr.new(af_unix, usize(max_unix_path_len) + 2) }
|
||||||
unsafe {
|
unsafe {
|
||||||
sock_addr.push(path.bytes()) or {}
|
sock_addr.push(path.bytes()) or {}
|
||||||
}
|
}
|
||||||
@@ -124,9 +124,9 @@ pub fn SocketAddr.new(af AddrFamily, size isize) SocketAddr {
|
|||||||
return sock_addr
|
return sock_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketAddr.from_ptr creates new socket address by copying data from specified pointer.
|
// SocketAddr.from_ptr_copy creates new socket address by copying data from specified pointer.
|
||||||
@[unsafe]
|
@[unsafe]
|
||||||
pub fn SocketAddr.from_ptr(ptr voidptr, size isize) !SocketAddr {
|
pub fn SocketAddr.from_ptr_copy(ptr voidptr, size isize) !SocketAddr {
|
||||||
if isnil(ptr) {
|
if isnil(ptr) {
|
||||||
return error('${@METHOD}: cannot accept nil ptr')
|
return error('${@METHOD}: cannot accept nil ptr')
|
||||||
}
|
}
|
||||||
@@ -140,6 +140,19 @@ pub fn SocketAddr.from_ptr(ptr voidptr, size isize) !SocketAddr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SocketAddr.from_ptr creates new socket address from specified pointer.
|
||||||
|
// Note: The data is reused, not copied. See also SocketAddr.from_ptr_copy().
|
||||||
|
@[unsafe]
|
||||||
|
pub fn SocketAddr.from_ptr(ptr voidptr, size isize) !SocketAddr {
|
||||||
|
if isnil(ptr) {
|
||||||
|
return error('${@METHOD}: cannot accept nil ptr')
|
||||||
|
}
|
||||||
|
return SocketAddr{
|
||||||
|
data: ptr
|
||||||
|
len: int(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// family returns the socket address family.
|
// family returns the socket address family.
|
||||||
// Note: It returns 0 if socket address is nil, see also `is_empty()`.
|
// Note: It returns 0 if socket address is nil, see also `is_empty()`.
|
||||||
pub fn (a SocketAddr) family() AddrFamily {
|
pub fn (a SocketAddr) family() AddrFamily {
|
||||||
@@ -195,13 +208,6 @@ pub fn (a SocketAddr) size() u32 {
|
|||||||
return u32(a.len)
|
return u32(a.len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// u8_array returns the socket address data as is as bytes array.
|
|
||||||
pub fn (a SocketAddr) u8_array() []u8 {
|
|
||||||
mut addr := []u8{len: int(a.size()), init: 0}
|
|
||||||
unsafe { vmemcpy(addr.data, a.ptr(), a.size()) }
|
|
||||||
return addr
|
|
||||||
}
|
|
||||||
|
|
||||||
// str returns the string representation of socket address.
|
// str returns the string representation of socket address.
|
||||||
// Supported address families are AF_INET, AF_INET6, and AF_UNIX.
|
// Supported address families are AF_INET, AF_INET6, and AF_UNIX.
|
||||||
// Examples: '172.16.16.132:1080', '[fdf1:72d1:0033:0000:0000:0000:0000:0247]:25535',
|
// Examples: '172.16.16.132:1080', '[fdf1:72d1:0033:0000:0000:0000:0000:0247]:25535',
|
||||||
@@ -242,10 +248,10 @@ pub fn (a SocketAddr) str() string {
|
|||||||
return '[' + res + ']:' + port_int.str()
|
return '[' + res + ']:' + port_int.str()
|
||||||
}
|
}
|
||||||
af_unix {
|
af_unix {
|
||||||
mut path := [max_unix_path_size]u8{}
|
mut path := [max_unix_path_len]u8{}
|
||||||
mut res := ''
|
mut res := ''
|
||||||
unsafe {
|
unsafe {
|
||||||
vmemcpy(path, a.ptr() + 2, max_unix_path_size)
|
vmemcpy(path, a.ptr() + 2, max_unix_path_len)
|
||||||
res = tos_clone(&u8(path[..].data))
|
res = tos_clone(&u8(path[..].data))
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
|||||||
+4
-4
@@ -1,17 +1,17 @@
|
|||||||
import netio
|
import netio
|
||||||
|
|
||||||
fn test_socket_addr_ipv4() {
|
fn test_socket_addr_ipv4() {
|
||||||
addr := netio.SocketAddr.ipv4([u8(127), 0, 0, 1]!, 1080)
|
addr := netio.SocketAddr.new_ipv4([u8(127), 0, 0, 1]!, 1080)
|
||||||
assert addr.str() == '127.0.0.1:1080'
|
assert addr.str() == '127.0.0.1:1080'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_socket_addr_ipv6() {
|
fn test_socket_addr_ipv6() {
|
||||||
addr := netio.SocketAddr.ipv6([u8(0xfd), 0xf1, 0x72, 0xd1, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00,
|
addr := netio.SocketAddr.new_ipv6([u8(0xfd), 0xf1, 0x72, 0xd1, 0x00, 0x33, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x47]!, 25535, 0, 0)
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x47]!, 25535, 0, 0)
|
||||||
assert addr.str() == '[fdf1:72d1:0033:0000:0000:0000:0000:0247]:25535'
|
assert addr.str() == '[fdf1:72d1:0033:0000:0000:0000:0000:0247]:25535'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_socket_addr_unix() {
|
fn test_socket_addr_unix() {
|
||||||
addr := netio.SocketAddr.unix('/run/app.sock')!
|
addr := netio.SocketAddr.new_unix('/run/app.sock')!
|
||||||
assert addr.str() == '/run/app.sock'
|
assert addr.str() == '/run/app.sock'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user