@@ -3,7 +3,7 @@ mod tests;
3
3
4
4
use crate :: fmt;
5
5
use crate :: io:: { self , ErrorKind } ;
6
- use crate :: net:: { Ipv4Addr , Ipv6Addr , SocketAddr , ToSocketAddrs } ;
6
+ use crate :: net:: { Ipv4Addr , Ipv6Addr , SocketAddr , SocketAddrFamily , ToSocketAddrs } ;
7
7
use crate :: sys_common:: net as net_imp;
8
8
use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
9
9
use crate :: time:: Duration ;
@@ -811,3 +811,100 @@ impl fmt::Debug for UdpSocket {
811
811
self . 0 . fmt ( f)
812
812
}
813
813
}
814
+
815
+ /// A UDP Socket that is not bound to a `SocketAddr` yet.
816
+ ///
817
+ /// This socket is designed to support socket configurations _before_
818
+ /// binding to a `SocketAddr`. After configurations, this socket
819
+ /// can be bound and translated into a [`UdpSocket`].
820
+ ///
821
+ /// # Example
822
+ ///
823
+ /// ```no_run
824
+ /// #![feature(unbound_socket)]
825
+ /// use std::net::{SocketAddr, SocketAddrFamily, UnboundUdpSocket};
826
+ ///
827
+ /// fn main() -> std::io::Result<()> {
828
+ /// let unbound_socket = UnboundUdpSocket::new(SocketAddrFamily::InetV4)?;
829
+ /// unbound_socket.set_reuseaddr(true)?;
830
+ /// let addr = SocketAddr::from(([127, 0, 0, 1], 5500));
831
+ /// let _udp_socket = unbound_socket.bind(&addr)?;
832
+ /// Ok(())
833
+ /// }
834
+ /// ```
835
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
836
+ pub struct UnboundUdpSocket {
837
+ inner : net_imp:: UnboundUdpSocket ,
838
+ }
839
+
840
+ impl UnboundUdpSocket {
841
+ /// Creates a new unbound UDP socket with `addr_family`.
842
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
843
+ pub fn new ( addr_family : SocketAddrFamily ) -> io:: Result < UnboundUdpSocket > {
844
+ let inner = net_imp:: UnboundUdpSocket :: new ( addr_family) ?;
845
+ Ok ( Self { inner } )
846
+ }
847
+
848
+ /// Sets `SO_REUSEADDR` option for the socket.
849
+ ///
850
+ /// In general, this option allows a second caller to bind to a `(addr, port)` again,
851
+ /// where the `addr` could be the `unspecified` address. However it behaves with subtle
852
+ /// differences on different platforms. Please be sure to check your platform for
853
+ /// the exact expected behaviors.
854
+ ///
855
+ /// This method can only be called before `bind`, otherwise will fail.
856
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
857
+ pub fn set_reuseaddr ( & self , enable : bool ) -> io:: Result < ( ) > {
858
+ self . inner . set_reuseaddr ( enable)
859
+ }
860
+
861
+ /// Sets `SO_REUSEPORT` option for the socket.
862
+ ///
863
+ /// In general, this option allows a second caller to bind to a same `(addr, port)`
864
+ /// pair again, if the first caller has enabled this option too. Please check with
865
+ /// your specific platform for the details of the behavior.
866
+ ///
867
+ /// This option is only available for UNIX-like platforms and not Windows platforms.
868
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
869
+ pub fn set_reuseport ( & self , enable : bool ) -> io:: Result < ( ) > {
870
+ self . inner . set_reuseport ( enable)
871
+ }
872
+
873
+ /// Sets `SO_EXCLUSIVEADDRUSE` option for the socket.
874
+ ///
875
+ /// This option is only available in Windows. Its purpose is to prevent
876
+ /// any other caller to "reuse" the same (addr, port), even if they call
877
+ /// `set_reuseaddr(true)`. This method returns an error on non-Windows platforms.
878
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
879
+ pub fn set_exclusiveaddruse ( & self , enable : bool ) -> io:: Result < ( ) > {
880
+ self . inner . set_exclusiveaddruse ( enable)
881
+ }
882
+
883
+ /// Binds to `addr`, consumes this unbound socket and returns a [`UdpSocket`].
884
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
885
+ pub fn bind ( self , addr : & SocketAddr ) -> io:: Result < UdpSocket > {
886
+ let net_imp = self . inner . bind ( addr) ?;
887
+ Ok ( UdpSocket ( net_imp) )
888
+ }
889
+ }
890
+
891
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
892
+ impl fmt:: Debug for UnboundUdpSocket {
893
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
894
+ self . inner . fmt ( f)
895
+ }
896
+ }
897
+
898
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
899
+ impl AsInner < net_imp:: UnboundUdpSocket > for UnboundUdpSocket {
900
+ fn as_inner ( & self ) -> & net_imp:: UnboundUdpSocket {
901
+ & self . inner
902
+ }
903
+ }
904
+
905
+ #[ unstable( feature = "unbound_socket" , issue = "none" ) ]
906
+ impl IntoInner < net_imp:: UnboundUdpSocket > for UnboundUdpSocket {
907
+ fn into_inner ( self ) -> net_imp:: UnboundUdpSocket {
908
+ self . inner
909
+ }
910
+ }
0 commit comments