1
1
use super :: TcpStream ;
2
- use crate :: io:: Socket ;
3
- use std:: { io, net:: SocketAddr } ;
2
+ use crate :: io:: { SharedFd , Socket } ;
3
+ use std:: {
4
+ io,
5
+ net:: SocketAddr ,
6
+ os:: unix:: prelude:: { AsRawFd , FromRawFd , RawFd } ,
7
+ } ;
4
8
5
9
/// A TCP socket server, listening for connections.
6
10
///
@@ -53,6 +57,41 @@ impl TcpListener {
53
57
Ok ( TcpListener { inner : socket } )
54
58
}
55
59
60
+ /// Creates new `TcpListener` from a previously bound `std::net::TcpListener`.
61
+ ///
62
+ /// This function is intended to be used to wrap a TCP listener from the
63
+ /// standard library in the tokio-uring equivalent. The conversion assumes nothing
64
+ /// about the underlying socket; it is left up to the user to decide what socket
65
+ /// options are appropriate for their use case.
66
+ ///
67
+ /// This can be used in conjunction with socket2's `Socket` interface to
68
+ /// configure a socket before it's handed off, such as setting options like
69
+ /// `reuse_address` or binding to multiple addresses.
70
+ ///
71
+ /// # Example
72
+ ///
73
+ /// ```
74
+ /// tokio_uring::start(async {
75
+ /// let address: std::net::SocketAddr = "[::0]:8443".parse().unwrap();
76
+ /// let socket = tokio::net::TcpSocket::new_v6().unwrap();
77
+ /// socket.set_reuseaddr(true).unwrap();
78
+ /// socket.set_reuseport(true).unwrap();
79
+ /// socket.bind(address).unwrap();
80
+ ///
81
+ /// let listener = socket.listen(1024).unwrap();
82
+ ///
83
+ /// let listener = tokio_uring::net::TcpListener::from_std(listener.into_std().unwrap());
84
+ /// })
85
+ /// ```
86
+ pub fn from_std ( socket : std:: net:: TcpListener ) -> Self {
87
+ let inner = Socket :: from_std ( socket) ;
88
+ Self { inner }
89
+ }
90
+
91
+ pub ( crate ) fn from_socket ( inner : Socket ) -> Self {
92
+ Self { inner }
93
+ }
94
+
56
95
/// Returns the local address that this listener is bound to.
57
96
///
58
97
/// This can be useful, for example, when binding to port 0 to
@@ -70,8 +109,6 @@ impl TcpListener {
70
109
/// assert_eq!(addr, SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
71
110
/// ```
72
111
pub fn local_addr ( & self ) -> io:: Result < SocketAddr > {
73
- use std:: os:: unix:: io:: { AsRawFd , FromRawFd } ;
74
-
75
112
let fd = self . inner . as_raw_fd ( ) ;
76
113
// SAFETY: Our fd is the handle the kernel has given us for a TcpListener.
77
114
// Create a std::net::TcpListener long enough to call its local_addr method
@@ -98,3 +135,15 @@ impl TcpListener {
98
135
Ok ( ( stream, socket_addr) )
99
136
}
100
137
}
138
+
139
+ impl FromRawFd for TcpListener {
140
+ unsafe fn from_raw_fd ( fd : RawFd ) -> Self {
141
+ TcpListener :: from_socket ( Socket :: from_shared_fd ( SharedFd :: new ( fd) ) )
142
+ }
143
+ }
144
+
145
+ impl AsRawFd for TcpListener {
146
+ fn as_raw_fd ( & self ) -> RawFd {
147
+ self . inner . as_raw_fd ( )
148
+ }
149
+ }
0 commit comments