| 73 | } |
| 74 | |
| 75 | func (c *connIO) recvLoop() { |
| 76 | defer func() { |
| 77 | // withdraw bindings & tunnels when we exit. We need to use the coordinator context here, since |
| 78 | // our own context might be canceled, but we still need to withdraw. |
| 79 | b := binding{ |
| 80 | bKey: bKey(c.UniqueID()), |
| 81 | kind: proto.CoordinateResponse_PeerUpdate_LOST, |
| 82 | } |
| 83 | if c.disconnected { |
| 84 | b.kind = proto.CoordinateResponse_PeerUpdate_DISCONNECTED |
| 85 | } |
| 86 | if err := agpl.SendCtx(c.coordCtx, c.bindings, b); err != nil { |
| 87 | c.logger.Debug(c.coordCtx, "parent context expired while withdrawing bindings", slog.Error(err)) |
| 88 | } |
| 89 | // only remove tunnels on graceful disconnect. If we remove tunnels for lost peers, then |
| 90 | // this will look like a disconnect from the peer perspective, since we query for active peers |
| 91 | // by using the tunnel as a join in the database |
| 92 | if c.disconnected { |
| 93 | t := tunnel{ |
| 94 | tKey: tKey{src: c.UniqueID()}, |
| 95 | active: false, |
| 96 | } |
| 97 | if err := agpl.SendCtx(c.coordCtx, c.tunnels, t); err != nil { |
| 98 | c.logger.Debug(c.coordCtx, "parent context expired while withdrawing tunnels", slog.Error(err)) |
| 99 | } |
| 100 | } |
| 101 | }() |
| 102 | defer c.Close() |
| 103 | for { |
| 104 | select { |
| 105 | case <-c.coordCtx.Done(): |
| 106 | c.logger.Debug(c.coordCtx, "exiting io recvLoop; coordinator exit") |
| 107 | _ = c.Enqueue(&proto.CoordinateResponse{Error: agpl.CloseErrCoordinatorClose}) |
| 108 | return |
| 109 | case <-c.peerCtx.Done(): |
| 110 | c.logger.Debug(c.peerCtx, "exiting io recvLoop; peer context canceled") |
| 111 | return |
| 112 | case req, ok := <-c.requests: |
| 113 | if !ok { |
| 114 | c.logger.Debug(c.peerCtx, "exiting io recvLoop; requests chan closed") |
| 115 | return |
| 116 | } |
| 117 | if err := c.handleRequest(req); err != nil { |
| 118 | if !xerrors.Is(err, errDisconnect) { |
| 119 | _ = c.Enqueue(&proto.CoordinateResponse{Error: err.Error()}) |
| 120 | } |
| 121 | return |
| 122 | } |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | var errDisconnect = xerrors.New("graceful disconnect") |
| 128 | |