mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-17 22:29:54 +00:00
Add error code handling
This commit is contained in:
@@ -2,6 +2,7 @@ package peer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
@@ -209,7 +210,11 @@ func (conn *Conn) Open(engineCtx context.Context) error {
|
|||||||
// both peer send offer
|
// both peer send offer
|
||||||
if err := conn.handshaker.SendOffer(); err != nil {
|
if err := conn.handshaker.SendOffer(); err != nil {
|
||||||
conn.Log.Errorf("failed to send offer: %v", err)
|
conn.Log.Errorf("failed to send offer: %v", err)
|
||||||
conn.guard.FailedToSendOffer()
|
// if remote peer is offline, no need to try to reconnect.
|
||||||
|
// The remote peer when online will send an offer to us
|
||||||
|
if !errors.Is(err, ErrPeerNotAvailable) {
|
||||||
|
conn.guard.FailedToSendOffer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.opened = true
|
conn.opened = true
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package peer
|
package peer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/pion/ice/v4"
|
"github.com/pion/ice/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
@@ -9,6 +11,8 @@ import (
|
|||||||
sProto "github.com/netbirdio/netbird/shared/signal/proto"
|
sProto "github.com/netbirdio/netbird/shared/signal/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrPeerNotAvailable = signal.ErrPeerNotAvailable
|
||||||
|
|
||||||
type Signaler struct {
|
type Signaler struct {
|
||||||
signal signal.Client
|
signal signal.Client
|
||||||
wgPrivateKey wgtypes.Key
|
wgPrivateKey wgtypes.Key
|
||||||
@@ -68,6 +72,9 @@ func (s *Signaler) signalOfferAnswer(offerAnswer OfferAnswer, remoteKey string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err = s.signal.SendWithDeliveryCheck(msg); err != nil {
|
if err = s.signal.SendWithDeliveryCheck(msg); err != nil {
|
||||||
|
if errors.Is(err, signal.ErrPeerNotAvailable) {
|
||||||
|
return ErrPeerNotAvailable
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -22,6 +23,10 @@ import (
|
|||||||
"github.com/netbirdio/netbird/shared/signal/proto"
|
"github.com/netbirdio/netbird/shared/signal/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrPeerNotAvailable = errors.New("peer not available")
|
||||||
|
)
|
||||||
|
|
||||||
// ConnStateNotifier is a wrapper interface of the status recorder
|
// ConnStateNotifier is a wrapper interface of the status recorder
|
||||||
type ConnStateNotifier interface {
|
type ConnStateNotifier interface {
|
||||||
MarkSignalDisconnected(error)
|
MarkSignalDisconnected(error)
|
||||||
@@ -410,6 +415,17 @@ func (c *GrpcClient) SendWithDeliveryCheck(msg *proto.Message) error {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
_, err = c.realClient.SendWithDeliveryCheck(ctx, encryptedMessage)
|
_, err = c.realClient.SendWithDeliveryCheck(ctx, encryptedMessage)
|
||||||
|
if err != nil {
|
||||||
|
if st, ok := status.FromError(err); ok {
|
||||||
|
switch st.Code() {
|
||||||
|
case codes.NotFound:
|
||||||
|
return ErrPeerNotAvailable
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("grpc error %s: %w", st.Code(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err // Not a gRPC status error
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,11 @@ func (s *Server) Send(ctx context.Context, msg *proto.EncryptedMessage) (*proto.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendWithDeliveryCheck forwards a message to the signal peer with error handling
|
// SendWithDeliveryCheck forwards a message to the signal peer with error handling
|
||||||
|
// When the remote peer is not connected it returns codes.NotFound error, otherwise it returns other types of errors
|
||||||
|
// that can be retried. In case codes.NotFound is returned the caller should not retry sending the message. The remote
|
||||||
|
// peer should send a new offer to re-establish the connection when it comes back online.
|
||||||
|
// Todo: double check the thread safe registry management. When both peer come online at the same time then both peers
|
||||||
|
// might not be registered yet when the first message is sent.
|
||||||
func (s *Server) SendWithDeliveryCheck(ctx context.Context, msg *proto.EncryptedMessage) (*emptypb.Empty, error) {
|
func (s *Server) SendWithDeliveryCheck(ctx context.Context, msg *proto.EncryptedMessage) (*emptypb.Empty, error) {
|
||||||
log.Tracef("received a new message to send from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
log.Tracef("received a new message to send from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
||||||
|
|
||||||
@@ -113,8 +118,7 @@ func (s *Server) SendWithDeliveryCheck(ctx context.Context, msg *proto.Encrypted
|
|||||||
s.forwardMessageToPeer(ctx, msg)
|
s.forwardMessageToPeer(ctx, msg)
|
||||||
return &emptypb.Empty{}, nil
|
return &emptypb.Empty{}, nil
|
||||||
}
|
}
|
||||||
|
return nil, status.Errorf(codes.NotFound, "remote peer not connected")
|
||||||
return nil, status.Errorf(codes.FailedPrecondition, "remote peer not connected")
|
|
||||||
//return s.dispatcher.SendMessage(ctx, msg)
|
//return s.dispatcher.SendMessage(ctx, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user