Implement lb_tcpsocket
This commit is contained in:
parent
2fe9515702
commit
bcb734846d
@ -6,7 +6,10 @@
|
||||
//! See [`lb_netlib`] for items exported by this library.
|
||||
use derive_more::{From, FromStr};
|
||||
use luaffi::{cdef, metatype};
|
||||
use std::net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||
use std::{
|
||||
net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
time::Duration,
|
||||
};
|
||||
use thiserror::Error;
|
||||
use tokio::net::{TcpListener, TcpSocket, TcpStream};
|
||||
|
||||
@ -99,39 +102,66 @@ impl lb_netlib {
|
||||
/// If `port` is not specified, `0` is used as the default.
|
||||
pub extern "Lua" fn socketaddr(&self, s: any, port: any) -> Result<lb_socketaddr> {
|
||||
if port != () {
|
||||
self.__new_socketaddr(self.ipaddr(s), port)
|
||||
self.__new_skaddr(self.ipaddr(s), port)
|
||||
} else {
|
||||
if __istype(__ct.lb_socketaddr, s) {
|
||||
__new(__ct.lb_socketaddr, s) // copy constructor
|
||||
} else if __istype(__ct.lb_ipaddr, s) {
|
||||
self.__new_socketaddr(s, 0) // default port 0
|
||||
self.__new_skaddr(s, 0) // default port 0
|
||||
} else {
|
||||
self.__parse_socketaddr(s)
|
||||
self.__parse_skaddr(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "Lua-C" fn __new_socketaddr(&self, ip: &lb_ipaddr, port: u16) -> lb_socketaddr {
|
||||
extern "Lua-C" fn __new_skaddr(&self, ip: &lb_ipaddr, port: u16) -> lb_socketaddr {
|
||||
SocketAddr::new(ip.0, port).into()
|
||||
}
|
||||
|
||||
extern "Lua-C" fn __parse_socketaddr(&self, s: &str) -> Result<lb_socketaddr> {
|
||||
extern "Lua-C" fn __parse_skaddr(&self, s: &str) -> Result<lb_socketaddr> {
|
||||
Ok(s.parse()?)
|
||||
}
|
||||
|
||||
/// Creates a new TCP socket configured for IPv4.
|
||||
///
|
||||
/// See [`TcpSocket::new_v4`].
|
||||
pub extern "Lua-C" fn tcp_v4(&self) -> Result<lb_tcpsocket> {
|
||||
pub extern "Lua-C" fn tcp(&self) -> Result<lb_tcpsocket> {
|
||||
Ok(Some(TcpSocket::new_v4()?).into())
|
||||
}
|
||||
|
||||
/// Creates a new TCP socket configured for IPv6.
|
||||
///
|
||||
/// See [`TcpSocket::new_v6`].
|
||||
pub extern "Lua-C" fn tcp_v6(&self) -> Result<lb_tcpsocket> {
|
||||
pub extern "Lua-C" fn tcp6(&self) -> Result<lb_tcpsocket> {
|
||||
Ok(Some(TcpSocket::new_v6()?).into())
|
||||
}
|
||||
|
||||
pub extern "Lua" fn bind_tcp(&self, addr: any, port: any) -> Result<lb_tcpsocket> {
|
||||
let addr = self.socketaddr(addr, port);
|
||||
let socket;
|
||||
if addr.ip().is_v6() {
|
||||
socket = self.tcp6();
|
||||
} else {
|
||||
socket = self.tcp();
|
||||
}
|
||||
socket.bind(addr);
|
||||
socket
|
||||
}
|
||||
|
||||
pub extern "Lua" fn connect_tcp(&self, addr: any, port: any) -> Result<lb_tcpstream> {
|
||||
let addr = self.socketaddr(addr, port);
|
||||
let socket;
|
||||
if addr.ip().is_v6() {
|
||||
socket = self.tcp6();
|
||||
} else {
|
||||
socket = self.tcp();
|
||||
}
|
||||
socket.connect(addr)
|
||||
}
|
||||
|
||||
pub extern "Lua" fn listen_tcp(&self, addr: any, port: any) -> Result<lb_tcplistener> {
|
||||
self.bind_tcp(addr, port).listen(1024)
|
||||
}
|
||||
}
|
||||
|
||||
/// An IP address, either IPv4 or IPv6.
|
||||
@ -322,8 +352,116 @@ pub struct lb_tcpsocket(#[opaque] Option<TcpSocket>);
|
||||
|
||||
#[metatype]
|
||||
impl lb_tcpsocket {
|
||||
fn socket(&self) -> Result<&TcpSocket> {
|
||||
self.0.as_ref().ok_or(Error::SocketConsumed)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::keepalive`].
|
||||
pub extern "Lua-C" fn keepalive(&self) -> Result<bool> {
|
||||
todo!()
|
||||
Ok(self.socket()?.keepalive()?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::set_keepalive`].
|
||||
pub extern "Lua-C" fn set_keepalive(&self, enabled: bool) -> Result<()> {
|
||||
Ok(self.socket()?.set_keepalive(enabled)?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::reuseaddr`].
|
||||
pub extern "Lua-C" fn reuseaddr(&self) -> Result<bool> {
|
||||
Ok(self.socket()?.reuseaddr()?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::set_reuseaddr`].
|
||||
pub extern "Lua-C" fn set_reuseaddr(&self, enabled: bool) -> Result<()> {
|
||||
Ok(self.socket()?.set_reuseaddr(enabled)?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::reuseport`].
|
||||
pub extern "Lua-C" fn reuseport(&self) -> Result<bool> {
|
||||
Ok(self.socket()?.reuseport()?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::set_reuseport`].
|
||||
pub extern "Lua-C" fn set_reuseport(&self, enabled: bool) -> Result<()> {
|
||||
Ok(self.socket()?.set_reuseport(enabled)?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::send_buffer_size`].
|
||||
pub extern "Lua-C" fn sendbuf(&self) -> Result<u32> {
|
||||
Ok(self.socket()?.send_buffer_size()?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::set_send_buffer_size`].
|
||||
pub extern "Lua-C" fn set_sendbuf(&self, size: u32) -> Result<()> {
|
||||
Ok(self.socket()?.set_send_buffer_size(size)?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::recv_buffer_size`].
|
||||
pub extern "Lua-C" fn recvbuf(&self) -> Result<u32> {
|
||||
Ok(self.socket()?.recv_buffer_size()?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::set_recv_buffer_size`].
|
||||
pub extern "Lua-C" fn set_recvbuf(&self, size: u32) -> Result<()> {
|
||||
Ok(self.socket()?.set_recv_buffer_size(size)?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::linger`].
|
||||
pub extern "Lua-C" fn linger(&self) -> Result<f64> {
|
||||
Ok(self
|
||||
.socket()?
|
||||
.linger()?
|
||||
.map(|n| n.as_secs_f64())
|
||||
.unwrap_or(0.))
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::set_linger`].
|
||||
pub extern "Lua-C" fn set_linger(&self, secs: f64) -> Result<()> {
|
||||
Ok(self
|
||||
.socket()?
|
||||
.set_linger((secs != 0.).then_some(Duration::from_secs_f64(secs)))?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::nodelay`].
|
||||
pub extern "Lua-C" fn nodelay(&self) -> Result<bool> {
|
||||
Ok(self.socket()?.nodelay()?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::set_nodelay`].
|
||||
pub extern "Lua-C" fn set_nodelay(&self, enabled: bool) -> Result<()> {
|
||||
Ok(self.socket()?.set_nodelay(enabled)?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::tos`].
|
||||
pub extern "Lua-C" fn tos(&self) -> Result<u32> {
|
||||
Ok(self.socket()?.tos()?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::set_tos`].
|
||||
pub extern "Lua-C" fn set_tos(&self, tos: u32) -> Result<()> {
|
||||
Ok(self.socket()?.set_tos(tos)?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::local_addr`].
|
||||
pub extern "Lua-C" fn local_addr(&self) -> Result<lb_socketaddr> {
|
||||
Ok(self.socket()?.local_addr()?.into())
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::bind`].
|
||||
pub extern "Lua-C" fn bind(&self, addr: &lb_socketaddr) -> Result<()> {
|
||||
Ok(self.socket()?.bind(addr.0)?)
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::connect`].
|
||||
pub async extern "Lua-C" fn connect(&mut self, addr: &lb_socketaddr) -> Result<lb_tcpstream> {
|
||||
let socket = self.0.take().ok_or(Error::SocketConsumed)?;
|
||||
Ok(socket.connect(addr.0).await?.into())
|
||||
}
|
||||
|
||||
/// See [`TcpSocket::listen`].
|
||||
pub extern "Lua-C" fn listen(&mut self, backlog: u32) -> Result<lb_tcplistener> {
|
||||
let socket = self.0.take().ok_or(Error::SocketConsumed)?;
|
||||
Ok(socket.listen(backlog)?.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user