fix(dgram): erase late readiness keys
- commit
- 2bd81b93b4c770b28c51b634f42bb2e1d00e7787
- author
- brice · · 2026-07-23 20:36 UTC
- parent
- 4175002
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +36 -6
M internal/adapters/dgram/ssh_dialer.go +15 -6
| @@ -198,15 +198,24 @@ func (d RemoteDialer) Dial(ctx context.Context) (ports.Transport, error) { | |||
| 198 | 198 | return t, nil | |
| 199 | 199 | } | |
| 200 | 200 | ||
| 201 | - | func readUDPReadyContext(ctx context.Context, r io.Reader) (udpReady, error) { | |
| 202 | - | type result struct { | |
| 203 | - | ready udpReady | |
| 204 | - | err error | |
| 201 | + | type udpReadyResult struct { | |
| 202 | + | ready udpReady | |
| 203 | + | err error | |
| 204 | + | } | |
| 205 | + | ||
| 206 | + | func deliverUDPReady(ctx context.Context, ch chan<- udpReadyResult, res udpReadyResult) { | |
| 207 | + | select { | |
| 208 | + | case ch <- res: | |
| 209 | + | case <-ctx.Done(): | |
| 210 | + | pdgram.Erase(res.ready.key) | |
| 205 | 211 | } | |
| 206 | - | ch := make(chan result, 1) | |
| 212 | + | } | |
| 213 | + | ||
| 214 | + | func readUDPReadyContext(ctx context.Context, r io.Reader) (udpReady, error) { | |
| 215 | + | ch := make(chan udpReadyResult) | |
| 207 | 216 | go func() { | |
| 208 | 217 | ready, err := readUDPReady(r) | |
| 209 | - | ch <- result{ready: ready, err: err} | |
| 218 | + | deliverUDPReady(ctx, ch, udpReadyResult{ready: ready, err: err}) | |
| 210 | 219 | }() | |
| 211 | 220 | select { | |
| 212 | 221 | case res := <-ch: | |
| @@ -198,15 +198,24 @@ func (d RemoteDialer) Dial(ctx context.Context) (ports.Transport, error) { | |||||
| 198 | return t, nil | 198 | return t, nil | ||
| 199 | } | 199 | } | ||
| 200 | 200 | ||||
| 201 | - | func readUDPReadyContext(ctx context.Context, r io.Reader) (udpReady, error) { | 201 | + | type udpReadyResult struct { |
| 202 | - | type result struct { | 202 | + | ready udpReady |
| 203 | - | ready udpReady | 203 | + | err error |
| 204 | - | err error | 204 | + | } |
| 205 | + | ||||
| 206 | + | func deliverUDPReady(ctx context.Context, ch chan<- udpReadyResult, res udpReadyResult) { | |||
| 207 | + | select { | |||
| 208 | + | case ch <- res: | |||
| 209 | + | case <-ctx.Done(): | |||
| 210 | + | pdgram.Erase(res.ready.key) | |||
| 205 | } | 211 | } | ||
| 206 | - | ch := make(chan result, 1) | 212 | + | } |
| 213 | + | ||||
| 214 | + | func readUDPReadyContext(ctx context.Context, r io.Reader) (udpReady, error) { | |||
| 215 | + | ch := make(chan udpReadyResult) | |||
| 207 | go func() { | 216 | go func() { | ||
| 208 | ready, err := readUDPReady(r) | 217 | ready, err := readUDPReady(r) | ||
| 209 | - | ch <- result{ready: ready, err: err} | 218 | + | deliverUDPReady(ctx, ch, udpReadyResult{ready: ready, err: err}) |
| 210 | }() | 219 | }() | ||
| 211 | select { | 220 | select { | ||
| 212 | case res := <-ch: | 221 | case res := <-ch: | ||
M internal/adapters/dgram/ssh_dialer_test.go +21 -0
| @@ -174,6 +174,27 @@ type closeTrackPacketConn struct { | |||
| 174 | 174 | ||
| 175 | 175 | func (c closeTrackPacketConn) Close() error { *c.closed = true; return c.PacketConn.Close() } | |
| 176 | 176 | ||
| 177 | + | func TestDeliverUDPReadyErasesParsedKeyAfterCancellation(t *testing.T) { | |
| 178 | + | ctx, cancel := context.WithCancel(context.Background()) | |
| 179 | + | cancel() | |
| 180 | + | key := make([]byte, pdgram.KeySize) | |
| 181 | + | for i := range key { | |
| 182 | + | key[i] = byte(i + 1) | |
| 183 | + | } | |
| 184 | + | ready, err := readUDPReady(strings.NewReader("VEV-UDP 1234 " + base64.StdEncoding.EncodeToString(key) + "\n")) | |
| 185 | + | if err != nil { | |
| 186 | + | t.Fatal(err) | |
| 187 | + | } | |
| 188 | + | ||
| 189 | + | deliverUDPReady(ctx, make(chan udpReadyResult), udpReadyResult{ready: ready}) | |
| 190 | + | ||
| 191 | + | for i, b := range ready.key { | |
| 192 | + | if b != 0 { | |
| 193 | + | t.Fatalf("key[%d] = %d, want erased", i, b) | |
| 194 | + | } | |
| 195 | + | } | |
| 196 | + | } | |
| 197 | + | ||
| 177 | 198 | func TestReadUDPReady(t *testing.T) { | |
| 178 | 199 | key := base64.StdEncoding.EncodeToString(make([]byte, pdgram.KeySize)) | |
| 179 | 200 | tests := []struct { | |
| @@ -174,6 +174,27 @@ type closeTrackPacketConn struct { | |||||
| 174 | 174 | ||||
| 175 | func (c closeTrackPacketConn) Close() error { *c.closed = true; return c.PacketConn.Close() } | 175 | func (c closeTrackPacketConn) Close() error { *c.closed = true; return c.PacketConn.Close() } | ||
| 176 | 176 | ||||
| 177 | + | func TestDeliverUDPReadyErasesParsedKeyAfterCancellation(t *testing.T) { | |||
| 178 | + | ctx, cancel := context.WithCancel(context.Background()) | |||
| 179 | + | cancel() | |||
| 180 | + | key := make([]byte, pdgram.KeySize) | |||
| 181 | + | for i := range key { | |||
| 182 | + | key[i] = byte(i + 1) | |||
| 183 | + | } | |||
| 184 | + | ready, err := readUDPReady(strings.NewReader("VEV-UDP 1234 " + base64.StdEncoding.EncodeToString(key) + "\n")) | |||
| 185 | + | if err != nil { | |||
| 186 | + | t.Fatal(err) | |||
| 187 | + | } | |||
| 188 | + | ||||
| 189 | + | deliverUDPReady(ctx, make(chan udpReadyResult), udpReadyResult{ready: ready}) | |||
| 190 | + | ||||
| 191 | + | for i, b := range ready.key { | |||
| 192 | + | if b != 0 { | |||
| 193 | + | t.Fatalf("key[%d] = %d, want erased", i, b) | |||
| 194 | + | } | |||
| 195 | + | } | |||
| 196 | + | } | |||
| 197 | + | ||||
| 177 | func TestReadUDPReady(t *testing.T) { | 198 | func TestReadUDPReady(t *testing.T) { | ||
| 178 | key := base64.StdEncoding.EncodeToString(make([]byte, pdgram.KeySize)) | 199 | key := base64.StdEncoding.EncodeToString(make([]byte, pdgram.KeySize)) | ||
| 179 | tests := []struct { | 200 | tests := []struct { | ||