@@ -688,6 +688,8 @@ enum SocketState {
688688 addr : SocketAddr ,
689689 } ,
690690 Closed {
691+ /// The addr to rebind to when recovering.
692+ addr : SocketAddr ,
691693 last_max_gso_segments : NonZeroUsize ,
692694 last_gro_segments : NonZeroUsize ,
693695 last_may_fragment : bool ,
@@ -768,25 +770,34 @@ impl SocketState {
768770 }
769771
770772 fn rebind ( & mut self ) -> io:: Result < ( ) > {
771- let ( addr, closed_state) = match self {
772- Self :: Connected { state, addr, .. } => {
773- let s = SocketState :: Closed {
774- last_max_gso_segments : state. max_gso_segments ( ) ,
775- last_gro_segments : state. gro_segments ( ) ,
776- last_may_fragment : state. may_fragment ( ) ,
777- } ;
778- ( * addr, s)
779- }
780- Self :: Closed { .. } => {
781- return Err ( io:: Error :: other ( "socket is closed and cannot be rebound" ) ) ;
782- }
773+ let addr = match self {
774+ Self :: Connected { addr, .. } => * addr,
775+ Self :: Closed { addr, .. } => * addr,
783776 } ;
784777 debug ! ( "rebinding {}" , addr) ;
785778
786- * self = closed_state;
787- * self = Self :: bind ( addr) ?;
779+ // Transition to Closed first to drop the old socket.
780+ // This is needed so the port is released before we try to bind again.
781+ if let Self :: Connected { state, .. } = self {
782+ * self = SocketState :: Closed {
783+ addr,
784+ last_max_gso_segments : state. max_gso_segments ( ) ,
785+ last_gro_segments : state. gro_segments ( ) ,
786+ last_may_fragment : state. may_fragment ( ) ,
787+ } ;
788+ }
788789
789- Ok ( ( ) )
790+ match Self :: bind ( addr) {
791+ Ok ( new_state) => {
792+ * self = new_state;
793+ Ok ( ( ) )
794+ }
795+ Err ( err) => {
796+ // Stay in Closed state but allow future rebind attempts
797+ debug ! ( "rebind failed, will retry on next attempt: {}" , err) ;
798+ Err ( err)
799+ }
800+ }
790801 }
791802
792803 fn is_closed ( & self ) -> bool {
@@ -795,8 +806,9 @@ impl SocketState {
795806
796807 fn close ( & mut self ) -> Option < ( tokio:: net:: UdpSocket , quinn_udp:: UdpSocketState ) > {
797808 match self {
798- Self :: Connected { state, .. } => {
809+ Self :: Connected { state, addr , .. } => {
799810 let s = SocketState :: Closed {
811+ addr : * addr,
800812 last_max_gso_segments : state. max_gso_segments ( ) ,
801813 last_gro_segments : state. gro_segments ( ) ,
802814 last_may_fragment : state. may_fragment ( ) ,
0 commit comments