fix(remote): close stale attachment handshakes safely
- commit
- d63c59a4c7bd874c8f07034c28d36016583b3fde
- author
- brice · · 2026-08-08 17:16 UTC
- parent
- 92a7932
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +7 -7
M internal/usecase/daemon/daemon.go +6 -6
| @@ -1167,10 +1167,7 @@ func (d *Daemon) handleHelloWithContext(handshakeCtx context.Context, timedOut < | |||
| 1167 | 1167 | if admitted { | |
| 1168 | 1168 | welcomeTicket.End() | |
| 1169 | 1169 | } | |
| 1170 | - | if !d.abortResumeClaim(ac) { | |
| 1171 | - | d.clientGone(sess, ac, tr, false) | |
| 1172 | - | } | |
| 1173 | - | _ = tr.Close() | |
| 1170 | + | failAttachment() | |
| 1174 | 1171 | return | |
| 1175 | 1172 | } | |
| 1176 | 1173 | if err := handshakeCtx.Err(); err != nil { | |
| @@ -1199,27 +1196,30 @@ func (d *Daemon) handleHelloWithContext(handshakeCtx context.Context, timedOut < | |||
| 1199 | 1196 | failAttachment() | |
| 1200 | 1197 | return | |
| 1201 | 1198 | } | |
| 1202 | - | if postWelcomeLease != nil && (rc == nil || !rc.markAttachmentReady(postWelcomeLease)) { | |
| 1199 | + | postWelcomeRC := sess.renderCoordinator() | |
| 1200 | + | if postWelcomeLease != nil && (postWelcomeRC == nil || !postWelcomeRC.markAttachmentReady(postWelcomeLease)) { | |
| 1203 | 1201 | postWelcomeTicket.End() | |
| 1204 | 1202 | // The attachment was detached while Welcome was in flight; never let | |
| 1205 | 1203 | // this stale handshake emit an Output frame. | |
| 1206 | 1204 | failAttachment() | |
| 1207 | 1205 | return | |
| 1208 | 1206 | } | |
| 1209 | - | postWelcomeTicket.End() | |
| 1210 | 1207 | paintToken := sess.attachmentToken(ac, tr) | |
| 1211 | 1208 | painted := make(chan bool, 1) | |
| 1212 | 1209 | if err := boundedHandshakeOperation(handshakeCtx, tr, func() error { | |
| 1213 | 1210 | painted <- d.firstPaintForTransition(paintToken) | |
| 1214 | 1211 | return nil | |
| 1215 | 1212 | }); err != nil { | |
| 1213 | + | postWelcomeTicket.End() | |
| 1216 | 1214 | failAttachment() | |
| 1217 | 1215 | return | |
| 1218 | 1216 | } | |
| 1219 | 1217 | if !<-painted || handshakeCtx.Err() != nil { | |
| 1218 | + | postWelcomeTicket.End() | |
| 1220 | 1219 | failAttachment() | |
| 1221 | 1220 | return | |
| 1222 | 1221 | } | |
| 1222 | + | postWelcomeTicket.End() | |
| 1223 | 1223 | if !d.commitResumeClaim(ac) { | |
| 1224 | 1224 | failAttachment() | |
| 1225 | 1225 | return | |
| @@ -1167,10 +1167,7 @@ func (d *Daemon) handleHelloWithContext(handshakeCtx context.Context, timedOut < | |||||
| 1167 | if admitted { | 1167 | if admitted { | ||
| 1168 | welcomeTicket.End() | 1168 | welcomeTicket.End() | ||
| 1169 | } | 1169 | } | ||
| 1170 | - | if !d.abortResumeClaim(ac) { | 1170 | + | failAttachment() |
| 1171 | - | d.clientGone(sess, ac, tr, false) | |||
| 1172 | - | } | |||
| 1173 | - | _ = tr.Close() | |||
| 1174 | return | 1171 | return | ||
| 1175 | } | 1172 | } | ||
| 1176 | if err := handshakeCtx.Err(); err != nil { | 1173 | if err := handshakeCtx.Err(); err != nil { | ||
| @@ -1199,27 +1196,30 @@ func (d *Daemon) handleHelloWithContext(handshakeCtx context.Context, timedOut < | |||||
| 1199 | failAttachment() | 1196 | failAttachment() | ||
| 1200 | return | 1197 | return | ||
| 1201 | } | 1198 | } | ||
| 1202 | - | if postWelcomeLease != nil && (rc == nil || !rc.markAttachmentReady(postWelcomeLease)) { | 1199 | + | postWelcomeRC := sess.renderCoordinator() |
| 1200 | + | if postWelcomeLease != nil && (postWelcomeRC == nil || !postWelcomeRC.markAttachmentReady(postWelcomeLease)) { | |||
| 1203 | postWelcomeTicket.End() | 1201 | postWelcomeTicket.End() | ||
| 1204 | // The attachment was detached while Welcome was in flight; never let | 1202 | // The attachment was detached while Welcome was in flight; never let | ||
| 1205 | // this stale handshake emit an Output frame. | 1203 | // this stale handshake emit an Output frame. | ||
| 1206 | failAttachment() | 1204 | failAttachment() | ||
| 1207 | return | 1205 | return | ||
| 1208 | } | 1206 | } | ||
| 1209 | - | postWelcomeTicket.End() | |||
| 1210 | paintToken := sess.attachmentToken(ac, tr) | 1207 | paintToken := sess.attachmentToken(ac, tr) | ||
| 1211 | painted := make(chan bool, 1) | 1208 | painted := make(chan bool, 1) | ||
| 1212 | if err := boundedHandshakeOperation(handshakeCtx, tr, func() error { | 1209 | if err := boundedHandshakeOperation(handshakeCtx, tr, func() error { | ||
| 1213 | painted <- d.firstPaintForTransition(paintToken) | 1210 | painted <- d.firstPaintForTransition(paintToken) | ||
| 1214 | return nil | 1211 | return nil | ||
| 1215 | }); err != nil { | 1212 | }); err != nil { | ||
| 1213 | + | postWelcomeTicket.End() | |||
| 1216 | failAttachment() | 1214 | failAttachment() | ||
| 1217 | return | 1215 | return | ||
| 1218 | } | 1216 | } | ||
| 1219 | if !<-painted || handshakeCtx.Err() != nil { | 1217 | if !<-painted || handshakeCtx.Err() != nil { | ||
| 1218 | + | postWelcomeTicket.End() | |||
| 1220 | failAttachment() | 1219 | failAttachment() | ||
| 1221 | return | 1220 | return | ||
| 1222 | } | 1221 | } | ||
| 1222 | + | postWelcomeTicket.End() | |||
| 1223 | if !d.commitResumeClaim(ac) { | 1223 | if !d.commitResumeClaim(ac) { | ||
| 1224 | failAttachment() | 1224 | failAttachment() | ||
| 1225 | return | 1225 | return | ||
M internal/usecase/daemon/picker.go +1 -1
| @@ -940,7 +940,7 @@ func (d *Daemon) remotePickerTargetReady(key domain.RemoteSessionKey) bool { | |||
| 940 | 940 | } | |
| 941 | 941 | for _, session := range entry.Sessions { | |
| 942 | 942 | if session.Name == key.Name { | |
| 943 | - | return true | |
| 943 | + | return !remoteSessionStateStopped(session.State) && session.State != "broken" | |
| 944 | 944 | } | |
| 945 | 945 | } | |
| 946 | 946 | return false | |
| @@ -940,7 +940,7 @@ func (d *Daemon) remotePickerTargetReady(key domain.RemoteSessionKey) bool { | |||||
| 940 | } | 940 | } | ||
| 941 | for _, session := range entry.Sessions { | 941 | for _, session := range entry.Sessions { | ||
| 942 | if session.Name == key.Name { | 942 | if session.Name == key.Name { | ||
| 943 | - | return true | 943 | + | return !remoteSessionStateStopped(session.State) && session.State != "broken" |
| 944 | } | 944 | } | ||
| 945 | } | 945 | } | ||
| 946 | return false | 946 | return false | ||