diff --git a/README.md b/README.md index ed27ff8..53748cb 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,11 @@ **netio** is a networking library for V programming language. This implementation aims to be as flexible and portable. It heavily relies on the libc. + +Differences with the V standard library **net** module: + +* Provides the low-level wrappers around C API functions. +* Supports any kind of: socket type, socket option, address family and protocol. + +**netio** provides a high-level abstractions over BSD sockets: `TCPListener`, +`TCPStream`, `UDPSocket`. diff --git a/af_darwin.c.v b/af_darwin.c.v index 0c380b7..6a60756 100644 --- a/af_darwin.c.v +++ b/af_darwin.c.v @@ -4,41 +4,41 @@ module netio Address families defined on Darwin. */ -pub const af_appletalk = AddrFamily(u16(C.AF_APPLETALK)) -pub const af_ccitt = AddrFamily(u16(C.AF_CCITT)) -pub const af_chaos = AddrFamily(u16(C.AF_CHAOS)) -pub const af_cnt = AddrFamily(u16(C.AF_CNT)) -pub const af_coip = AddrFamily(u16(C.AF_COIP)) -pub const af_datakit = AddrFamily(u16(C.AF_DATAKIT)) -pub const af_decnet = AddrFamily(u16(C.AF_DECnet)) -pub const af_dli = AddrFamily(u16(C.AF_DLI)) -pub const af_e164 = AddrFamily(u16(C.AF_E164)) -pub const af_ecma = AddrFamily(u16(C.AF_ECMA)) -pub const af_hylink = AddrFamily(u16(C.AF_HYLINK)) -pub const af_ieee80211 = AddrFamily(u16(C.AF_IEEE80211)) -pub const af_implink = AddrFamily(u16(C.AF_IMPLINK)) -pub const af_inet6 = AddrFamily(u16(C.AF_INET6)) -pub const af_inet = AddrFamily(u16(C.AF_INET)) -pub const af_ipx = AddrFamily(u16(C.AF_IPX)) -pub const af_isdn = AddrFamily(u16(C.AF_ISDN)) -pub const af_iso = AddrFamily(u16(C.AF_ISO)) -pub const af_lat = AddrFamily(u16(C.AF_LAT)) -pub const af_link = AddrFamily(u16(C.AF_LINK)) -pub const af_local = AddrFamily(u16(C.AF_LOCAL)) -pub const af_max = AddrFamily(u16(C.AF_MAX)) -pub const af_natm = AddrFamily(u16(C.AF_NATM)) -pub const af_ndrv = AddrFamily(u16(C.AF_NDRV)) -pub const af_netbios = AddrFamily(u16(C.AF_NETBIOS)) -pub const af_ns = AddrFamily(u16(C.AF_NS)) -pub const af_osi = AddrFamily(u16(C.AF_OSI)) -pub const af_ppp = AddrFamily(u16(C.AF_PPP)) -pub const af_pup = AddrFamily(u16(C.AF_PUP)) -pub const af_reserved_36 = AddrFamily(u16(C.AF_RESERVED_36)) -pub const af_route = AddrFamily(u16(C.AF_ROUTE)) -pub const af_sip = AddrFamily(u16(C.AF_SIP)) -pub const af_sna = AddrFamily(u16(C.AF_SNA)) -pub const af_system = AddrFamily(u16(C.AF_SYSTEM)) -pub const af_unix = AddrFamily(u16(C.AF_UNIX)) -pub const af_unspec = AddrFamily(u16(C.AF_UNSPEC)) -pub const af_utun = AddrFamily(u16(C.AF_UTUN)) -pub const af_vsock = AddrFamily(u16(C.AF_VSOCK)) +pub const af_appletalk = AddrFamily(C.AF_APPLETALK) +pub const af_ccitt = AddrFamily(C.AF_CCITT) +pub const af_chaos = AddrFamily(C.AF_CHAOS) +pub const af_cnt = AddrFamily(C.AF_CNT) +pub const af_coip = AddrFamily(C.AF_COIP) +pub const af_datakit = AddrFamily(C.AF_DATAKIT) +pub const af_decnet = AddrFamily(C.AF_DECnet) +pub const af_dli = AddrFamily(C.AF_DLI) +pub const af_e164 = AddrFamily(C.AF_E164) +pub const af_ecma = AddrFamily(C.AF_ECMA) +pub const af_hylink = AddrFamily(C.AF_HYLINK) +pub const af_ieee80211 = AddrFamily(C.AF_IEEE80211) +pub const af_implink = AddrFamily(C.AF_IMPLINK) +pub const af_inet6 = AddrFamily(C.AF_INET6) +pub const af_inet = AddrFamily(C.AF_INET) +pub const af_ipx = AddrFamily(C.AF_IPX) +pub const af_isdn = AddrFamily(C.AF_ISDN) +pub const af_iso = AddrFamily(C.AF_ISO) +pub const af_lat = AddrFamily(C.AF_LAT) +pub const af_link = AddrFamily(C.AF_LINK) +pub const af_local = AddrFamily(C.AF_LOCAL) +pub const af_max = AddrFamily(C.AF_MAX) +pub const af_natm = AddrFamily(C.AF_NATM) +pub const af_ndrv = AddrFamily(C.AF_NDRV) +pub const af_netbios = AddrFamily(C.AF_NETBIOS) +pub const af_ns = AddrFamily(C.AF_NS) +pub const af_osi = AddrFamily(C.AF_OSI) +pub const af_ppp = AddrFamily(C.AF_PPP) +pub const af_pup = AddrFamily(C.AF_PUP) +pub const af_reserved_36 = AddrFamily(C.AF_RESERVED_36) +pub const af_route = AddrFamily(C.AF_ROUTE) +pub const af_sip = AddrFamily(C.AF_SIP) +pub const af_sna = AddrFamily(C.AF_SNA) +pub const af_system = AddrFamily(C.AF_SYSTEM) +pub const af_unix = AddrFamily(C.AF_UNIX) +pub const af_unspec = AddrFamily(C.AF_UNSPEC) +pub const af_utun = AddrFamily(C.AF_UTUN) +pub const af_vsock = AddrFamily(C.AF_VSOCK) diff --git a/af_default.c.v b/af_default.c.v index 4e556a3..a2c401c 100644 --- a/af_default.c.v +++ b/af_default.c.v @@ -4,7 +4,7 @@ module netio Well defined address families. Must work on all platforms. */ -pub const af_unspec = AddrFamily(u16(C.AF_UNSPEC)) -pub const af_unix = AddrFamily(u16(C.AF_UNIX)) -pub const af_inet = AddrFamily(u16(C.AF_INET)) -pub const af_inet6 = AddrFamily(u16(C.AF_INET6)) +pub const af_unspec = AddrFamily(C.AF_UNSPEC) +pub const af_unix = AddrFamily(C.AF_UNIX) +pub const af_inet = AddrFamily(C.AF_INET) +pub const af_inet6 = AddrFamily(C.AF_INET6) diff --git a/af_freebsd.c.v b/af_freebsd.c.v index c46f482..b239173 100644 --- a/af_freebsd.c.v +++ b/af_freebsd.c.v @@ -4,93 +4,93 @@ module netio Address families defined on FreeBSD. */ -pub const af_appletalk = AddrFamily(u16(C.AF_APPLETALK)) -pub const af_arp = AddrFamily(u16(C.AF_ARP)) -pub const af_atm = AddrFamily(u16(C.AF_ATM)) -pub const af_bluetooth = AddrFamily(u16(C.AF_BLUETOOTH)) -pub const af_ccitt = AddrFamily(u16(C.AF_CCITT)) -pub const af_chaos = AddrFamily(u16(C.AF_CHAOS)) -pub const af_cnt = AddrFamily(u16(C.AF_CNT)) -pub const af_coip = AddrFamily(u16(C.AF_COIP)) -pub const af_datakit = AddrFamily(u16(C.AF_DATAKIT)) -pub const af_decnet = AddrFamily(u16(C.AF_DECnet)) -pub const af_divert = AddrFamily(u16(C.AF_DIVERT)) -pub const af_dli = AddrFamily(u16(C.AF_DLI)) -pub const af_e164 = AddrFamily(u16(C.AF_E164)) -pub const af_ecma = AddrFamily(u16(C.AF_ECMA)) -pub const af_hylink = AddrFamily(u16(C.AF_HYLINK)) -pub const af_hyperv = AddrFamily(u16(C.AF_HYPERV)) -pub const af_ieee80211 = AddrFamily(u16(C.AF_IEEE80211)) -pub const af_implink = AddrFamily(u16(C.AF_IMPLINK)) -pub const af_inet6 = AddrFamily(u16(C.AF_INET6)) -pub const af_inet6_sdp = AddrFamily(u16(C.AF_INET6_SDP)) -pub const af_inet = AddrFamily(u16(C.AF_INET)) -pub const af_inet_sdp = AddrFamily(u16(C.AF_INET_SDP)) -pub const af_ipfwlog = AddrFamily(u16(C.AF_IPFWLOG)) -pub const af_ipx = AddrFamily(u16(C.AF_IPX)) -pub const af_isdn = AddrFamily(u16(C.AF_ISDN)) -pub const af_iso = AddrFamily(u16(C.AF_ISO)) -pub const af_lat = AddrFamily(u16(C.AF_LAT)) -pub const af_link = AddrFamily(u16(C.AF_LINK)) -pub const af_local = AddrFamily(u16(C.AF_LOCAL)) -pub const af_max = AddrFamily(u16(C.AF_MAX)) -pub const af_natm = AddrFamily(u16(C.AF_NATM)) -pub const af_netbios = AddrFamily(u16(C.AF_NETBIOS)) -pub const af_netgraph = AddrFamily(u16(C.AF_NETGRAPH)) -pub const af_netlink = AddrFamily(u16(C.AF_NETLINK)) -pub const af_osi = AddrFamily(u16(C.AF_OSI)) -pub const af_pup = AddrFamily(u16(C.AF_PUP)) -pub const af_route = AddrFamily(u16(C.AF_ROUTE)) -pub const af_scluster = AddrFamily(u16(C.AF_SCLUSTER)) -pub const af_sip = AddrFamily(u16(C.AF_SIP)) -pub const af_slow = AddrFamily(u16(C.AF_SLOW)) -pub const af_sna = AddrFamily(u16(C.AF_SNA)) -pub const af_unix = AddrFamily(u16(C.AF_UNIX)) -pub const af_unspec = AddrFamily(u16(C.AF_UNSPEC)) -pub const af_vendor00 = AddrFamily(u16(C.AF_VENDOR00)) -pub const af_vendor01 = AddrFamily(u16(C.AF_VENDOR01)) -pub const af_vendor03 = AddrFamily(u16(C.AF_VENDOR03)) -pub const af_vendor04 = AddrFamily(u16(C.AF_VENDOR04)) -pub const af_vendor05 = AddrFamily(u16(C.AF_VENDOR05)) -pub const af_vendor06 = AddrFamily(u16(C.AF_VENDOR06)) -pub const af_vendor07 = AddrFamily(u16(C.AF_VENDOR07)) -pub const af_vendor08 = AddrFamily(u16(C.AF_VENDOR08)) -pub const af_vendor09 = AddrFamily(u16(C.AF_VENDOR09)) -pub const af_vendor10 = AddrFamily(u16(C.AF_VENDOR10)) -pub const af_vendor11 = AddrFamily(u16(C.AF_VENDOR11)) -pub const af_vendor12 = AddrFamily(u16(C.AF_VENDOR12)) -pub const af_vendor13 = AddrFamily(u16(C.AF_VENDOR13)) -pub const af_vendor14 = AddrFamily(u16(C.AF_VENDOR14)) -pub const af_vendor15 = AddrFamily(u16(C.AF_VENDOR15)) -pub const af_vendor16 = AddrFamily(u16(C.AF_VENDOR16)) -pub const af_vendor17 = AddrFamily(u16(C.AF_VENDOR17)) -pub const af_vendor18 = AddrFamily(u16(C.AF_VENDOR18)) -pub const af_vendor19 = AddrFamily(u16(C.AF_VENDOR19)) -pub const af_vendor20 = AddrFamily(u16(C.AF_VENDOR20)) -pub const af_vendor21 = AddrFamily(u16(C.AF_VENDOR21)) -pub const af_vendor22 = AddrFamily(u16(C.AF_VENDOR22)) -pub const af_vendor23 = AddrFamily(u16(C.AF_VENDOR23)) -pub const af_vendor24 = AddrFamily(u16(C.AF_VENDOR24)) -pub const af_vendor25 = AddrFamily(u16(C.AF_VENDOR25)) -pub const af_vendor26 = AddrFamily(u16(C.AF_VENDOR26)) -pub const af_vendor27 = AddrFamily(u16(C.AF_VENDOR27)) -pub const af_vendor28 = AddrFamily(u16(C.AF_VENDOR28)) -pub const af_vendor29 = AddrFamily(u16(C.AF_VENDOR29)) -pub const af_vendor30 = AddrFamily(u16(C.AF_VENDOR30)) -pub const af_vendor31 = AddrFamily(u16(C.AF_VENDOR31)) -pub const af_vendor32 = AddrFamily(u16(C.AF_VENDOR32)) -pub const af_vendor33 = AddrFamily(u16(C.AF_VENDOR33)) -pub const af_vendor34 = AddrFamily(u16(C.AF_VENDOR34)) -pub const af_vendor35 = AddrFamily(u16(C.AF_VENDOR35)) -pub const af_vendor36 = AddrFamily(u16(C.AF_VENDOR36)) -pub const af_vendor37 = AddrFamily(u16(C.AF_VENDOR37)) -pub const af_vendor38 = AddrFamily(u16(C.AF_VENDOR38)) -pub const af_vendor39 = AddrFamily(u16(C.AF_VENDOR39)) -pub const af_vendor40 = AddrFamily(u16(C.AF_VENDOR40)) -pub const af_vendor41 = AddrFamily(u16(C.AF_VENDOR41)) -pub const af_vendor42 = AddrFamily(u16(C.AF_VENDOR42)) -pub const af_vendor43 = AddrFamily(u16(C.AF_VENDOR43)) -pub const af_vendor44 = AddrFamily(u16(C.AF_VENDOR44)) -pub const af_vendor45 = AddrFamily(u16(C.AF_VENDOR45)) -pub const af_vendor46 = AddrFamily(u16(C.AF_VENDOR46)) -pub const af_vendor47 = AddrFamily(u16(C.AF_VENDOR47)) +pub const af_appletalk = AddrFamily(C.AF_APPLETALK) +pub const af_arp = AddrFamily(C.AF_ARP) +pub const af_atm = AddrFamily(C.AF_ATM) +pub const af_bluetooth = AddrFamily(C.AF_BLUETOOTH) +pub const af_ccitt = AddrFamily(C.AF_CCITT) +pub const af_chaos = AddrFamily(C.AF_CHAOS) +pub const af_cnt = AddrFamily(C.AF_CNT) +pub const af_coip = AddrFamily(C.AF_COIP) +pub const af_datakit = AddrFamily(C.AF_DATAKIT) +pub const af_decnet = AddrFamily(C.AF_DECnet) +pub const af_divert = AddrFamily(C.AF_DIVERT) +pub const af_dli = AddrFamily(C.AF_DLI) +pub const af_e164 = AddrFamily(C.AF_E164) +pub const af_ecma = AddrFamily(C.AF_ECMA) +pub const af_hylink = AddrFamily(C.AF_HYLINK) +pub const af_hyperv = AddrFamily(C.AF_HYPERV) +pub const af_ieee80211 = AddrFamily(C.AF_IEEE80211) +pub const af_implink = AddrFamily(C.AF_IMPLINK) +pub const af_inet6 = AddrFamily(C.AF_INET6) +pub const af_inet6_sdp = AddrFamily(C.AF_INET6_SDP) +pub const af_inet = AddrFamily(C.AF_INET) +pub const af_inet_sdp = AddrFamily(C.AF_INET_SDP) +pub const af_ipfwlog = AddrFamily(C.AF_IPFWLOG) +pub const af_ipx = AddrFamily(C.AF_IPX) +pub const af_isdn = AddrFamily(C.AF_ISDN) +pub const af_iso = AddrFamily(C.AF_ISO) +pub const af_lat = AddrFamily(C.AF_LAT) +pub const af_link = AddrFamily(C.AF_LINK) +pub const af_local = AddrFamily(C.AF_LOCAL) +pub const af_max = AddrFamily(C.AF_MAX) +pub const af_natm = AddrFamily(C.AF_NATM) +pub const af_netbios = AddrFamily(C.AF_NETBIOS) +pub const af_netgraph = AddrFamily(C.AF_NETGRAPH) +pub const af_netlink = AddrFamily(C.AF_NETLINK) +pub const af_osi = AddrFamily(C.AF_OSI) +pub const af_pup = AddrFamily(C.AF_PUP) +pub const af_route = AddrFamily(C.AF_ROUTE) +pub const af_scluster = AddrFamily(C.AF_SCLUSTER) +pub const af_sip = AddrFamily(C.AF_SIP) +pub const af_slow = AddrFamily(C.AF_SLOW) +pub const af_sna = AddrFamily(C.AF_SNA) +pub const af_unix = AddrFamily(C.AF_UNIX) +pub const af_unspec = AddrFamily(C.AF_UNSPEC) +pub const af_vendor00 = AddrFamily(C.AF_VENDOR00) +pub const af_vendor01 = AddrFamily(C.AF_VENDOR01) +pub const af_vendor03 = AddrFamily(C.AF_VENDOR03) +pub const af_vendor04 = AddrFamily(C.AF_VENDOR04) +pub const af_vendor05 = AddrFamily(C.AF_VENDOR05) +pub const af_vendor06 = AddrFamily(C.AF_VENDOR06) +pub const af_vendor07 = AddrFamily(C.AF_VENDOR07) +pub const af_vendor08 = AddrFamily(C.AF_VENDOR08) +pub const af_vendor09 = AddrFamily(C.AF_VENDOR09) +pub const af_vendor10 = AddrFamily(C.AF_VENDOR10) +pub const af_vendor11 = AddrFamily(C.AF_VENDOR11) +pub const af_vendor12 = AddrFamily(C.AF_VENDOR12) +pub const af_vendor13 = AddrFamily(C.AF_VENDOR13) +pub const af_vendor14 = AddrFamily(C.AF_VENDOR14) +pub const af_vendor15 = AddrFamily(C.AF_VENDOR15) +pub const af_vendor16 = AddrFamily(C.AF_VENDOR16) +pub const af_vendor17 = AddrFamily(C.AF_VENDOR17) +pub const af_vendor18 = AddrFamily(C.AF_VENDOR18) +pub const af_vendor19 = AddrFamily(C.AF_VENDOR19) +pub const af_vendor20 = AddrFamily(C.AF_VENDOR20) +pub const af_vendor21 = AddrFamily(C.AF_VENDOR21) +pub const af_vendor22 = AddrFamily(C.AF_VENDOR22) +pub const af_vendor23 = AddrFamily(C.AF_VENDOR23) +pub const af_vendor24 = AddrFamily(C.AF_VENDOR24) +pub const af_vendor25 = AddrFamily(C.AF_VENDOR25) +pub const af_vendor26 = AddrFamily(C.AF_VENDOR26) +pub const af_vendor27 = AddrFamily(C.AF_VENDOR27) +pub const af_vendor28 = AddrFamily(C.AF_VENDOR28) +pub const af_vendor29 = AddrFamily(C.AF_VENDOR29) +pub const af_vendor30 = AddrFamily(C.AF_VENDOR30) +pub const af_vendor31 = AddrFamily(C.AF_VENDOR31) +pub const af_vendor32 = AddrFamily(C.AF_VENDOR32) +pub const af_vendor33 = AddrFamily(C.AF_VENDOR33) +pub const af_vendor34 = AddrFamily(C.AF_VENDOR34) +pub const af_vendor35 = AddrFamily(C.AF_VENDOR35) +pub const af_vendor36 = AddrFamily(C.AF_VENDOR36) +pub const af_vendor37 = AddrFamily(C.AF_VENDOR37) +pub const af_vendor38 = AddrFamily(C.AF_VENDOR38) +pub const af_vendor39 = AddrFamily(C.AF_VENDOR39) +pub const af_vendor40 = AddrFamily(C.AF_VENDOR40) +pub const af_vendor41 = AddrFamily(C.AF_VENDOR41) +pub const af_vendor42 = AddrFamily(C.AF_VENDOR42) +pub const af_vendor43 = AddrFamily(C.AF_VENDOR43) +pub const af_vendor44 = AddrFamily(C.AF_VENDOR44) +pub const af_vendor45 = AddrFamily(C.AF_VENDOR45) +pub const af_vendor46 = AddrFamily(C.AF_VENDOR46) +pub const af_vendor47 = AddrFamily(C.AF_VENDOR47) diff --git a/af_linux.c.v b/af_linux.c.v index c8d4a36..fb10869 100644 --- a/af_linux.c.v +++ b/af_linux.c.v @@ -4,53 +4,53 @@ module netio Address families defined on Linux. */ -pub const af_alg = AddrFamily(u16(C.AF_ALG)) -pub const af_appletalk = AddrFamily(u16(C.AF_APPLETALK)) -pub const af_ash = AddrFamily(u16(C.AF_ASH)) -pub const af_atmpvc = AddrFamily(u16(C.AF_ATMPVC)) -pub const af_atmsvc = AddrFamily(u16(C.AF_ATMSVC)) -pub const af_ax25 = AddrFamily(u16(C.AF_AX25)) -pub const af_bluetooth = AddrFamily(u16(C.AF_BLUETOOTH)) -pub const af_bridge = AddrFamily(u16(C.AF_BRIDGE)) -pub const af_caif = AddrFamily(u16(C.AF_CAIF)) -pub const af_can = AddrFamily(u16(C.AF_CAN)) -pub const af_decnet = AddrFamily(u16(C.AF_DECnet)) -pub const af_econet = AddrFamily(u16(C.AF_ECONET)) -pub const af_file = AddrFamily(u16(C.AF_FILE)) -pub const af_ib = AddrFamily(u16(C.AF_IB)) -pub const af_ieee802154 = AddrFamily(u16(C.AF_IEEE802154)) -pub const af_inet6 = AddrFamily(u16(C.AF_INET6)) -pub const af_inet = AddrFamily(u16(C.AF_INET)) -pub const af_ipx = AddrFamily(u16(C.AF_IPX)) -pub const af_irda = AddrFamily(u16(C.AF_IRDA)) -pub const af_isdn = AddrFamily(u16(C.AF_ISDN)) -pub const af_iucv = AddrFamily(u16(C.AF_IUCV)) -pub const af_kcm = AddrFamily(u16(C.AF_KCM)) -pub const af_key = AddrFamily(u16(C.AF_KEY)) -pub const af_llc = AddrFamily(u16(C.AF_LLC)) -pub const af_local = AddrFamily(u16(C.AF_LOCAL)) -pub const af_max = AddrFamily(u16(C.AF_MAX)) -pub const af_mctp = AddrFamily(u16(C.AF_MCTP)) -pub const af_mpls = AddrFamily(u16(C.AF_MPLS)) -pub const af_netbeui = AddrFamily(u16(C.AF_NETBEUI)) -pub const af_netlink = AddrFamily(u16(C.AF_NETLINK)) -pub const af_netrom = AddrFamily(u16(C.AF_NETROM)) -pub const af_nfc = AddrFamily(u16(C.AF_NFC)) -pub const af_packet = AddrFamily(u16(C.AF_PACKET)) -pub const af_phonet = AddrFamily(u16(C.AF_PHONET)) -pub const af_pppox = AddrFamily(u16(C.AF_PPPOX)) -pub const af_qipcrtr = AddrFamily(u16(C.AF_QIPCRTR)) -pub const af_rds = AddrFamily(u16(C.AF_RDS)) -pub const af_rose = AddrFamily(u16(C.AF_ROSE)) -pub const af_route = AddrFamily(u16(C.AF_ROUTE)) -pub const af_rxrpc = AddrFamily(u16(C.AF_RXRPC)) -pub const af_security = AddrFamily(u16(C.AF_SECURITY)) -pub const af_smc = AddrFamily(u16(C.AF_SMC)) -pub const af_sna = AddrFamily(u16(C.AF_SNA)) -pub const af_tipc = AddrFamily(u16(C.AF_TIPC)) -pub const af_unix = AddrFamily(u16(C.AF_UNIX)) -pub const af_unspec = AddrFamily(u16(C.AF_UNSPEC)) -pub const af_vsock = AddrFamily(u16(C.AF_VSOCK)) -pub const af_wanpipe = AddrFamily(u16(C.AF_WANPIPE)) -pub const af_x25 = AddrFamily(u16(C.AF_X25)) -pub const af_xdp = AddrFamily(u16(C.AF_XDP)) +pub const af_alg = AddrFamily(C.AF_ALG) +pub const af_appletalk = AddrFamily(C.AF_APPLETALK) +pub const af_ash = AddrFamily(C.AF_ASH) +pub const af_atmpvc = AddrFamily(C.AF_ATMPVC) +pub const af_atmsvc = AddrFamily(C.AF_ATMSVC) +pub const af_ax25 = AddrFamily(C.AF_AX25) +pub const af_bluetooth = AddrFamily(C.AF_BLUETOOTH) +pub const af_bridge = AddrFamily(C.AF_BRIDGE) +pub const af_caif = AddrFamily(C.AF_CAIF) +pub const af_can = AddrFamily(C.AF_CAN) +pub const af_decnet = AddrFamily(C.AF_DECnet) +pub const af_econet = AddrFamily(C.AF_ECONET) +pub const af_file = AddrFamily(C.AF_FILE) +pub const af_ib = AddrFamily(C.AF_IB) +pub const af_ieee802154 = AddrFamily(C.AF_IEEE802154) +pub const af_inet6 = AddrFamily(C.AF_INET6) +pub const af_inet = AddrFamily(C.AF_INET) +pub const af_ipx = AddrFamily(C.AF_IPX) +pub const af_irda = AddrFamily(C.AF_IRDA) +pub const af_isdn = AddrFamily(C.AF_ISDN) +pub const af_iucv = AddrFamily(C.AF_IUCV) +pub const af_kcm = AddrFamily(C.AF_KCM) +pub const af_key = AddrFamily(C.AF_KEY) +pub const af_llc = AddrFamily(C.AF_LLC) +pub const af_local = AddrFamily(C.AF_LOCAL) +pub const af_max = AddrFamily(C.AF_MAX) +pub const af_mctp = AddrFamily(C.AF_MCTP) +pub const af_mpls = AddrFamily(C.AF_MPLS) +pub const af_netbeui = AddrFamily(C.AF_NETBEUI) +pub const af_netlink = AddrFamily(C.AF_NETLINK) +pub const af_netrom = AddrFamily(C.AF_NETROM) +pub const af_nfc = AddrFamily(C.AF_NFC) +pub const af_packet = AddrFamily(C.AF_PACKET) +pub const af_phonet = AddrFamily(C.AF_PHONET) +pub const af_pppox = AddrFamily(C.AF_PPPOX) +pub const af_qipcrtr = AddrFamily(C.AF_QIPCRTR) +pub const af_rds = AddrFamily(C.AF_RDS) +pub const af_rose = AddrFamily(C.AF_ROSE) +pub const af_route = AddrFamily(C.AF_ROUTE) +pub const af_rxrpc = AddrFamily(C.AF_RXRPC) +pub const af_security = AddrFamily(C.AF_SECURITY) +pub const af_smc = AddrFamily(C.AF_SMC) +pub const af_sna = AddrFamily(C.AF_SNA) +pub const af_tipc = AddrFamily(C.AF_TIPC) +pub const af_unix = AddrFamily(C.AF_UNIX) +pub const af_unspec = AddrFamily(C.AF_UNSPEC) +pub const af_vsock = AddrFamily(C.AF_VSOCK) +pub const af_wanpipe = AddrFamily(C.AF_WANPIPE) +pub const af_x25 = AddrFamily(C.AF_X25) +pub const af_xdp = AddrFamily(C.AF_XDP) diff --git a/ai_freebsd.c.v b/ai_freebsd.c.v new file mode 100644 index 0000000..5a2b407 --- /dev/null +++ b/ai_freebsd.c.v @@ -0,0 +1,16 @@ +module netio + +/* + getaddrinfo(3) flags defined on FreeBSD. +*/ + +pub const ai_addrconfig = C.AI_ADDRCONFIG +pub const ai_all = C.AI_ALL +pub const ai_canonname = C.AI_CANONNAME +pub const ai_default = C.AI_DEFAULT +pub const ai_mask = C.AI_MASK +pub const ai_numerichost = C.AI_NUMERICHOST +pub const ai_numericserv = C.AI_NUMERICSERV +pub const ai_passive = C.AI_PASSIVE +pub const ai_v4mapped = C.AI_V4MAPPED +pub const ai_v4mapped_cfg = C.AI_V4MAPPED_CFG diff --git a/ai_linux.c.v b/ai_linux.c.v new file mode 100644 index 0000000..ed137e3 --- /dev/null +++ b/ai_linux.c.v @@ -0,0 +1,13 @@ +module netio + +/* + getaddrinfo(3) flags defined on Linux. +*/ + +pub const ai_addrconfig = C.AI_ADDRCONFIG +pub const ai_canonname = C.AI_CANONNAME +pub const ai_all = C.AI_ALL +pub const ai_v4mapped = C.AI_V4MAPPED +pub const ai_numericserv = C.AI_NUMERICSERV +pub const ai_passive = C.AI_PASSIVE +pub const ai_numerichost = C.AI_NUMERICHOST diff --git a/examples/host_fqdn.v b/examples/host_fqdn.v new file mode 100644 index 0000000..25d9345 --- /dev/null +++ b/examples/host_fqdn.v @@ -0,0 +1,16 @@ +import netio +import os + +fn main() { + // Resolve the fully qualified domain name for host. + // This programm is analog for `hostname -f` command. + hostname := os.hostname()! + ai := netio.translate_addr(node: hostname, flags: netio.ai_canonname)! + mut fqdn := '' + for a in ai { + // Not needed to iterate over all entries, return the first one per getaddrinfo(3). + fqdn = a.canonical + break + } + println(fqdn) +} diff --git a/main.v b/main.v deleted file mode 100644 index 2075502..0000000 --- a/main.v +++ /dev/null @@ -1,45 +0,0 @@ -// import net -import netio -// import time -// import os - -fn main() { - listen_addr := netio.SocketAddr.ipv4([u8(127), 0, 0, 1]!, 1081) - eprintln(listen_addr.family()) - - // eprintln(listen_addr) - // mut socket := netio.Socket.new(netio.af_inet, .tcp, 0)! - // socket.bind(listen_addr)! - // socket.listen(10)! - // println('Server started...') - // for { - // conn_fd := socket.accept()!.fd - // mut sock := net.tcp_socket_from_handle_raw(conn_fd) - // mut conn := net.TcpConn{ - // sock: sock - // handle: conn_fd - // read_timeout: 30 * time.second - // write_timeout: 30 * time.second - // } - // read := conn.read_line() - // println('Data read: ${read}') - // net.close(conn_fd)! - // } - // socket.close()! - - // hostname := dump(os.hostname()!) - ai := netio.translate_addr( - node: 'localhost' - flags: C.AI_CANONNAME - family: netio.af_inet - sock_type: netio.sock_stream - )! - dump(ai.len) - for a in ai { - println(a) - // println('Protocol: ' + netio.protocol_by_number(a.protocol)!.name) - // println('Address: ' + a.addr.str()) - // println('Canonical name: ' + a.canonical) - // println('---') - } -} diff --git a/main.vv b/main.vv new file mode 100644 index 0000000..ded0adc --- /dev/null +++ b/main.vv @@ -0,0 +1,45 @@ +import netio + +fn main() { + ai := netio.translate_addr( + service: '1081' + sock_type: netio.sock_stream + family: netio.af_inet6 + flags: netio.ai_passive + )! + + mut socket := netio.Socket{} + mut listen_addr := netio.SocketAddr{} + + for a in ai { + socket = netio.Socket.new(a.family, a.sock_type, a.protocol)! + socket.set_option(C.IPPROTO_IPV6, C.IPV6_V6ONLY, 0)! + socket.bind(a.addr) or { + socket.close()! + continue + } + listen_addr = a.addr + break + } + + defer { + socket.close() or { panic(err) } + } + + socket.listen(10) or { + eprintln('LISTEN: ${err}') + exit(1) + } + + println('Listening on ${listen_addr}...') + for { + conn, remote_addr := socket.accept() or { + eprintln('ACCEPT: ${err}') + exit(1) + } + eprintln(netio.name(remote_addr)!) + eprintln('Remote address: ${remote_addr} | ${remote_addr.family()} | ${remote_addr.size()}') + eprintln(remote_addr.u8_array()) + conn.close()! + } +} diff --git a/netio.v b/netio.v index a214a18..17f7974 100644 --- a/netio.v +++ b/netio.v @@ -1,19 +1,13 @@ module netio -import sync - -fn init() { - netio_protoent_mutex = sync.new_mutex() -} - -fn cleanup() { - netio_protoent_mutex.destroy() - unsafe { free(netio_protoent_mutex) } -} - // The socket address family type. // See [address_families(7)](https://www.man7.org/linux/man-pages/man7/address_families.7.html). -pub type AddrFamily = u16 +pub type AddrFamily = int + +// The protocol number type. +// See [protocols(5)](https://man7.org/linux/man-pages/man5/protocols.5.html), +// and [getprotoent(3)](https://man7.org/linux/man-pages/man3/getprotoent.3.html) for details. +pub type Protocol = int // The socket type. pub type SocketType = int diff --git a/protocol/README.md b/protocol/README.md new file mode 100644 index 0000000..9661bc8 --- /dev/null +++ b/protocol/README.md @@ -0,0 +1,7 @@ +# Protocols Database + +The **protocol** module provides thread-safe access to the protocols database. + +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) +for details. diff --git a/protocol.c.v b/protocol/protocol.c.v similarity index 75% rename from protocol.c.v rename to protocol/protocol.c.v index 6f37309..6c7d16a 100644 --- a/protocol.c.v +++ b/protocol/protocol.c.v @@ -1,11 +1,20 @@ @[has_globals] -module netio +module protocol import os import sync // Mutex for accessing to protocol entries via getprotoent(3). -__global netio_protoent_mutex &sync.Mutex +__global netio_proto_mutex &sync.Mutex + +fn init() { + netio_proto_mutex = sync.new_mutex() +} + +fn cleanup() { + netio_proto_mutex.destroy() + unsafe { free(netio_proto_mutex) } +} struct C.protoent { p_name &char @@ -19,16 +28,6 @@ fn C.getprotobynumber(i32) &C.protoent fn C.setprotoent(i32) fn C.endprotoent() -// The protocol number type. -// See [protocols(5)](https://man7.org/linux/man-pages/man5/protocols.5.html), -// and [getprotoent(3)](https://man7.org/linux/man-pages/man3/getprotoent.3.html) for details. -pub type Protocol = int - -// entry returns the protocol entry from database. -pub fn (p Protocol) entry() !ProtocolEntry { - return protocol_by_number(p)! -} - pub struct ProtocolEntry { pub: name string // The official name of protocol. @@ -60,11 +59,11 @@ fn make_proto(ent C.protoent) ProtocolEntry { // protocols returns all protocol entries from database in arbitrary order. pub fn protocols() []ProtocolEntry { - netio_protoent_mutex.@lock() + netio_proto_mutex.@lock() C.setprotoent(1) defer { C.endprotoent() - netio_protoent_mutex.unlock() + netio_proto_mutex.unlock() } mut protos := []ProtocolEntry{} for { @@ -79,9 +78,9 @@ pub fn protocols() []ProtocolEntry { // protocol_by_name returns the protocol entry by name e.g. 'tcp', 'icmp'. pub fn protocol_by_name(name string) !ProtocolEntry { - netio_protoent_mutex.@lock() + netio_proto_mutex.@lock() defer { - netio_protoent_mutex.unlock() + netio_proto_mutex.unlock() } proto := C.getprotobyname(&char(name.str)) if isnil(proto) { @@ -92,9 +91,9 @@ pub fn protocol_by_name(name string) !ProtocolEntry { // protocol_by_number returns the protocol entry by protocol number. pub fn protocol_by_number(num int) !ProtocolEntry { - netio_protoent_mutex.@lock() + netio_proto_mutex.@lock() defer { - netio_protoent_mutex.unlock() + netio_proto_mutex.unlock() } proto := C.getprotobynumber(num) if isnil(proto) { diff --git a/sock_default.c.v b/sock_default.c.v index c4f2f56..7f70e4e 100644 --- a/sock_default.c.v +++ b/sock_default.c.v @@ -8,4 +8,3 @@ pub const sock_stream = SocketType(C.SOCK_STREAM) pub const sock_dgram = SocketType(C.SOCK_DGRAM) pub const sock_seqpacket = SocketType(C.SOCK_SEQPACKET) pub const sock_raw = SocketType(C.SOCK_RAW) -pub const sock_rdm = SocketType(C.SOCK_RDM) diff --git a/sock_freebsd.c.v b/sock_freebsd.c.v new file mode 100644 index 0000000..df26918 --- /dev/null +++ b/sock_freebsd.c.v @@ -0,0 +1,13 @@ +module netio + +/* + Socket types defined on FreeBSD. +*/ + +pub const sock_stream = SocketType(C.SOCK_STREAM) +pub const sock_dgram = SocketType(C.SOCK_DGRAM) +pub const sock_raw = SocketType(C.SOCK_RAW) +pub const sock_seqpacket = SocketType(C.SOCK_SEQPACKET) +pub const sock_cloexec = SocketType(C.SOCK_CLOEXEC) +pub const sock_clofork = SocketType(C.SOCK_CLOFORK) +pub const sock_nonblock = SocketType(C.SOCK_NONBLOCK) diff --git a/socket.c.v b/socket.c.v index 4b559db..7b46050 100644 --- a/socket.c.v +++ b/socket.c.v @@ -3,20 +3,23 @@ module netio import os #include +#include fn C.socket(i32, i32, i32) i32 fn C.bind(i32, voidptr, i32) i32 fn C.connect(i32, voidptr, i32) i32 fn C.listen(i32, i32) i32 -fn C.accept(i32, voidptr, i32) i32 +fn C.accept(i32, voidptr, voidptr) i32 fn C.shutdown(i32, i32) i32 fn C.close(i32) i32 fn C.setsockopt(i32, i32, i32, voidptr, i32) i32 fn C.getsockopt(i32, i32, i32, voidptr, i32) i32 +struct C.sockaddr_storage {} + pub struct Socket { pub: - fd int + fd int = -1 } // Socket.new creates new socket. @@ -32,6 +35,11 @@ pub fn Socket.new(domain AddrFamily, typ SocketType, protocol Protocol) !Socket } } +// typeof reports the actual socket type. +pub fn (s Socket) typeof() !SocketType { + return s.get_option_int(C.SOL_SOCKET, C.SO_TYPE)! +} + // Socket shutdown modes. See [shutdown(3p)](https://man7.org/linux/man-pages/man3/shutdown.3p.html) for details. pub enum Shutdown { read = C.SHUT_RD @@ -61,21 +69,38 @@ pub fn (s Socket) listen(backlog int) ! { } // accept accepts a new connection on a socket. -pub fn (s Socket) accept() !Socket { - new_fd := C.accept(s.fd, 0, 0) - if new_fd == -1 { +// The return values are the new socket connected to remote and the remote socket address. +pub fn (s Socket) accept() !(Socket, SocketAddr) { + mut sock_addr_storage := &C.sockaddr_storage{} + mut sock_addr_len := sizeof(C.sockaddr_storage) + fd := C.accept(s.fd, sock_addr_storage, &sock_addr_len) + if fd == -1 { return os.last_error() } - return Socket{ - fd: new_fd + sock := Socket{ + fd: fd } + sock_addr := unsafe { + SocketAddr.from_ptr(sock_addr_storage, sock_addr_len)! + } + return sock, sock_addr } // set_option sets the socket option. -pub fn (s Socket) set_option(level SocketLevel, option SocketOption, value int) ! {} +pub fn (s Socket) set_option(level SocketLevel, option SocketOption, value int) ! { + if C.setsockopt(s.fd, i32(level), i32(option), i32(value), sizeof(value)) == -1 { + return os.last_error() + } +} -// get_option gets the socket option. -pub fn (s Socket) get_option(level SocketLevel, option SocketOption) ! {} +// get_option gets the socket option as int. +pub fn (s Socket) get_option_int(level SocketLevel, option SocketOption) !int { + mut result := 0 + if C.getsockopt(s.fd, i32(level), i32(option), &result, sizeof(result)) == -1 { + return os.last_error() + } + return result +} // shutdown shut downs socket send and receive operations. pub fn (s Socket) shutdown(how Shutdown) ! { diff --git a/socket_addr.c.v b/socket_addr.c.v index 17f8a0a..131cf5d 100644 --- a/socket_addr.c.v +++ b/socket_addr.c.v @@ -1,6 +1,5 @@ module netio -import dlmalloc import encoding.binary import os @@ -18,9 +17,10 @@ mut: ai_next voidptr } -fn C.getaddrinfo(node &char, srvc &char, hints &C.addrinfo, res &&C.addrinfo) int -fn C.freeaddrinfo(info &C.addrinfo) +fn C.getaddrinfo(&char, &char, &C.addrinfo, &&C.addrinfo) i32 +fn C.freeaddrinfo(&C.addrinfo) +// max_unix_path_size value is used to pad the sockaddr_un struct. const max_unix_path_size = $if linux { 108 } $else $if windows { @@ -51,16 +51,16 @@ pub: flags int } -// translate_addr translates the network address. -// See also [getaddrinfo(3)](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html). +// translate_addr translates the network address. This is a low-level wrapper around +// the [getaddrinfo(3)](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html) C API. // Example: // ```v // import os // import netio // // // Resolve the host FQND -// addrs := netio.translate_addr(node: os.hostname()!, flags: C.AI_CANONNAME)! -// for addr in addrs { +// addr_info := netio.translate_addr(node: os.hostname()!, flags: ai_canonname)! +// for addr in addr_info { // println(addr.canonical) // } // ``` @@ -107,11 +107,10 @@ pub fn translate_addr(hints TranslateAddrHints) ![]AddrInfo { } // SocketAddr.ipv4 creates new AF_INET socket address. -// addr must be in big-endian byte order. +// addr must be set in network (big-endian) byte order. pub fn SocketAddr.ipv4(addr [4]u8, port u16) SocketAddr { - mut sock_addr := unsafe { SocketAddr.empty(af_inet, 16) } + mut sock_addr := unsafe { SocketAddr.new(af_inet, 16) } unsafe { - sock_addr.push(binary.little_endian_get_u16(u16(af_inet))) or {} sock_addr.push(binary.big_endian_get_u16(port)) or {} sock_addr.push(addr[..]) or {} } @@ -119,9 +118,10 @@ pub fn SocketAddr.ipv4(addr [4]u8, port u16) SocketAddr { } // SocketAddr.ipv6 creates new AF_INET6 socket address. -// addr must be in 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. pub fn SocketAddr.ipv6(addr [16]u8, port u16, flow_info u32, scope_id u32) SocketAddr { - mut sock_addr := unsafe { SocketAddr.empty(af_inet6, 28) } + mut sock_addr := unsafe { SocketAddr.new(af_inet6, 28) } unsafe { sock_addr.push(binary.big_endian_get_u16(port)) or {} sock_addr.push(binary.big_endian_get_u32(flow_info)) or {} @@ -132,22 +132,25 @@ pub fn SocketAddr.ipv6(addr [16]u8, port u16, flow_info u32, scope_id u32) Socke } // SocketAddr.unix creates new AF_UNIX socket address. -pub fn SocketAddr.unix(path string) SocketAddr { - mut sock_addr := unsafe { SocketAddr.empty(af_unix, usize(max_unix_path_size) + 2) } +pub fn SocketAddr.unix(path string) !SocketAddr { + if path.len > max_unix_path_size { + return error('Too long path to socket') + } + mut sock_addr := unsafe { SocketAddr.new(af_unix, usize(max_unix_path_size) + 2) } unsafe { sock_addr.push(path.bytes()) or {} } return sock_addr } -// SocketAddr.empty creates new instance of SocketAddr with specified address family and size. +// SocketAddr.new creates new instance of SocketAddr with specified address family and size. // -// Note: This function only allocates memory (zero filled) for the address, but **does not** -// initialize the address itself, you need to do that manually. The benefit is that you can -// create the any type of address. +// This function allocates memory (zero filled) for the address, but does not initialize +// the address itself, you need to do that manually. The benefit is that you can create the +// any kind of socket address. // -// Note: This function sets the address family for you. -// This field is always first and have 2-byte size (`u16` type). +// Note: This function sets the address family struct field for you, it is always first +// and 2-byte size (`u16` type). // // SocketAddr is a "constructor" for // [sockaddr(3type)](https://www.man7.org/linux/man-pages/man3/sockaddr.3type.html) objects. @@ -158,15 +161,15 @@ pub fn SocketAddr.unix(path string) SocketAddr { // A mistake while creating an address will crash your application. So this function is // marked as `unsafe`. // -// The example below creates a `sockaddr_in` struct describing the loopback IPv4-address +// The example below creates a sockaddr_in struct describing the loopback IPv4-address // 127.0.0.1 with port number 1080. Note the comment in the example. This is a fragment // of [sockaddr_in(3type)](https://www.man7.org/linux/man-pages/man3/sockaddr.3type.html) // manual page, which shows the target C struct. Summing the field sizes yields 8 // bytes, but we need to allocate 16 bytes according to the . // Data must be padded to sockaddr struct size which is 16 bytes. Each field is then -// written in turn, from top to bottom. Keep in mind that address family field (sin_family -// in this case) are already written. According to the manual page, the address and port -// are written using the network (big endian) byte order. +// written in turn, from top to bottom. Keep in mind that two-byte address family field +// (sin_family in this case) is already written. According to the manual page, the +// address and port are written using the network (big endian) byte order. // // Example: // ```v @@ -186,15 +189,15 @@ pub fn SocketAddr.unix(path string) SocketAddr { // // typedef uint32_t in_addr_t; // // typedef uint16_t in_port_t; // -// mut sa := unsafe { netio.SocketAddr.empty(u16(C.AF_INET), 16) } +// mut sa := unsafe { netio.SocketAddr.new(netio.af_inet, 16) } // unsafe { // sa.push(binary.big_endian_get_u16(u16(1080)))! // sa.push([u8(127), 0, 0, 1])! // } // ``` @[unsafe] -pub fn SocketAddr.empty(af AddrFamily, size isize) SocketAddr { - ptr := unsafe { dlmalloc.calloc(usize(size)) } +pub fn SocketAddr.new(af AddrFamily, size isize) SocketAddr { + ptr := unsafe { vcalloc(usize(size)) } mut sock_addr := SocketAddr{ data: ptr len: int(size) @@ -212,7 +215,7 @@ pub fn SocketAddr.empty(af AddrFamily, size isize) SocketAddr { // SocketAddr.from_ptr creates new socket address by copying data from specified pointer. @[unsafe] pub fn SocketAddr.from_ptr(ptr voidptr, size isize) !SocketAddr { - data := unsafe { dlmalloc.calloc(usize(size)) } + data := unsafe { vcalloc(usize(size)) } unsafe { vmemcpy(data, ptr, size) } @@ -222,7 +225,7 @@ pub fn SocketAddr.from_ptr(ptr voidptr, size isize) !SocketAddr { } } -struct SocketAddr { +pub struct SocketAddr { mut: data &u8 = unsafe { nil } len int @@ -231,7 +234,7 @@ mut: // family returns the socket address family. pub fn (a SocketAddr) family() AddrFamily { - mut f := u16(-1) + mut f := AddrFamily(0) unsafe { vmemcpy(&f, a.data, isize(2)) } return f } @@ -265,9 +268,16 @@ pub fn (a SocketAddr) size() u32 { 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. pub fn (a SocketAddr) str() string { - family := a.family() - match family { + match a.family() { af_inet { mut addr := [4]u8{} mut port := [2]u8{} @@ -276,7 +286,12 @@ pub fn (a SocketAddr) str() string { vmemcpy(addr, a.ptr() + 4, 4) } port_int := binary.big_endian_u16_fixed(port) - return '${addr[0]}.${addr[1]}.${addr[2]}.${addr[3]}:${port_int}' + // vfmt off + return addr[0].str() + '.' + + addr[1].str() + '.' + + addr[2].str() + '.' + + addr[3].str() + ':' + port_int.str() + // vfmt on } af_inet6 { mut addr := [16]u8{} @@ -293,7 +308,7 @@ pub fn (a SocketAddr) str() string { } } port_int := binary.big_endian_u16_fixed(port) - return res + ':' + port_int.str() + return '[' + res + ']:' + port_int.str() } af_unix { mut path := [max_unix_path_size]u8{} diff --git a/socket_addr_test.v b/socket_addr_test.v new file mode 100644 index 0000000..2df6ae0 --- /dev/null +++ b/socket_addr_test.v @@ -0,0 +1,17 @@ +import netio + +fn test_socket_addr_ipv4() { + addr := netio.SocketAddr.ipv4([u8(127), 0, 0, 1]!, 1080) + assert addr.str() == '127.0.0.1:1080' +} + +fn test_socket_addr_ipv6() { + addr := netio.SocketAddr.ipv6([u8(0xfd), 0xf1, 0x72, 0xd1, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x47]!, 25535, 0, 0) + assert addr.str() == '[fdf1:72d1:0033:0000:0000:0000:0000:0247]:25535' +} + +fn test_socket_addr_unix() { + addr := netio.SocketAddr.unix('/run/app.sock')! + assert addr.str() == '/run/app.sock' +} diff --git a/translate.c.v b/translate.c.v new file mode 100644 index 0000000..73aa98d --- /dev/null +++ b/translate.c.v @@ -0,0 +1,14 @@ +module netio + +import os + +fn C.getnameinfo(voidptr, i32, &char, i32, &char, i32, i32) i32 + +pub fn name(sa SocketAddr) !(string, string) { + mut addr := []u8{len: 16} + mut srv := []u8{len: 2} + if C.getnameinfo(sa.ptr(), sa.size(), addr.data, 16, srv.data, 2, C.NI_NUMERICHOST) == -1 { + return os.last_error() + } + return addr.str(), '' +}