mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-05 21:19:08 +02:00
Add doc
This commit is contained in:
@@ -18,6 +18,7 @@ const (
|
||||
bufferSize = 8820
|
||||
)
|
||||
|
||||
// Peer represents a peer connection
|
||||
type Peer struct {
|
||||
log *log.Entry
|
||||
idS string
|
||||
@@ -27,6 +28,7 @@ type Peer struct {
|
||||
store *Store
|
||||
}
|
||||
|
||||
// NewPeer creates a new Peer instance and prepare custom logging
|
||||
func NewPeer(id []byte, conn net.Conn, store *Store) *Peer {
|
||||
stringID := messages.HashIDToString(id)
|
||||
return &Peer{
|
||||
@@ -38,6 +40,9 @@ func NewPeer(id []byte, conn net.Conn, store *Store) *Peer {
|
||||
}
|
||||
}
|
||||
|
||||
// Work reads data from the connection
|
||||
// It manages the protocol (healthcheck, transport, close). Read the message and determine the message type and handle
|
||||
// the message accordingly.
|
||||
func (p *Peer) Work() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
hc := healthcheck.NewSender(ctx)
|
||||
@@ -75,13 +80,14 @@ func (p *Peer) Work() {
|
||||
}
|
||||
|
||||
// Write writes data to the connection
|
||||
// it has been called by the remote peer
|
||||
func (p *Peer) Write(b []byte) (int, error) {
|
||||
p.connMu.RLock()
|
||||
defer p.connMu.RUnlock()
|
||||
return p.conn.Write(b)
|
||||
}
|
||||
|
||||
// CloseGracefully closes the connection with the peer gracefully. Send a close message to the client and close the
|
||||
// connection.
|
||||
func (p *Peer) CloseGracefully(ctx context.Context) {
|
||||
p.connMu.Lock()
|
||||
_, err := p.writeWithTimeout(ctx, messages.MarshalCloseMsg())
|
||||
@@ -97,6 +103,7 @@ func (p *Peer) CloseGracefully(ctx context.Context) {
|
||||
defer p.connMu.Unlock()
|
||||
}
|
||||
|
||||
// String returns the peer ID
|
||||
func (p *Peer) String() string {
|
||||
return p.idS
|
||||
}
|
||||
|
||||
+31
-6
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"sync"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
"github.com/netbirdio/netbird/relay/metrics"
|
||||
)
|
||||
|
||||
// Relay represents the relay server
|
||||
type Relay struct {
|
||||
metrics *metrics.Metrics
|
||||
validator auth.Validator
|
||||
@@ -25,6 +27,21 @@ type Relay struct {
|
||||
closeMu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewRelay creates a new Relay instance
|
||||
//
|
||||
// Parameters:
|
||||
// meter: An instance of metric.Meter from the go.opentelemetry.io/otel/metric package. It is used to create and manage
|
||||
// metrics for the relay server.
|
||||
// exposedAddress: A string representing the address that the relay server is exposed on. The client will use this
|
||||
// address as the relay server's instance URL.
|
||||
// tlsSupport: A boolean indicating whether the relay server supports TLS (Transport Layer Security) or not. The
|
||||
// instance URL depends on this value.
|
||||
// validator: An instance of auth.Validator from the auth package. It is used to validate the authentication of the
|
||||
// peers.
|
||||
//
|
||||
// Returns:
|
||||
// A pointer to a Relay instance and an error. If the Relay instance is successfully created, the error is nil.
|
||||
// Otherwise, the error contains the details of what went wrong.
|
||||
func NewRelay(meter metric.Meter, exposedAddress string, tlsSupport bool, validator auth.Validator) (*Relay, error) {
|
||||
m, err := metrics.NewMetrics(meter)
|
||||
if err != nil {
|
||||
@@ -42,10 +59,15 @@ func NewRelay(meter metric.Meter, exposedAddress string, tlsSupport bool, valida
|
||||
} else {
|
||||
r.instanceURL = fmt.Sprintf("rel://%s", exposedAddress)
|
||||
}
|
||||
_, err = url.ParseRequestURI(r.instanceURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid exposed address: %v", err)
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Accept start to handle a new peer connection
|
||||
func (r *Relay) Accept(conn net.Conn) {
|
||||
r.closeMu.RLock()
|
||||
defer r.closeMu.RUnlock()
|
||||
@@ -53,7 +75,7 @@ func (r *Relay) Accept(conn net.Conn) {
|
||||
return
|
||||
}
|
||||
|
||||
peerID, err := r.handShake(conn)
|
||||
peerID, err := r.handshake(conn)
|
||||
if err != nil {
|
||||
log.Errorf("failed to handshake with %s: %s", conn.RemoteAddr(), err)
|
||||
cErr := conn.Close()
|
||||
@@ -75,6 +97,8 @@ func (r *Relay) Accept(conn net.Conn) {
|
||||
}()
|
||||
}
|
||||
|
||||
// Close closes the relay server
|
||||
// It closes the connection with all peers in gracefully and stops accepting new connections.
|
||||
func (r *Relay) Close(ctx context.Context) {
|
||||
log.Infof("close connection with all peers")
|
||||
r.closeMu.Lock()
|
||||
@@ -91,7 +115,12 @@ func (r *Relay) Close(ctx context.Context) {
|
||||
r.closeMu.Unlock()
|
||||
}
|
||||
|
||||
func (r *Relay) handShake(conn net.Conn) ([]byte, error) {
|
||||
// InstanceURL returns the instance URL of the relay server
|
||||
func (r *Relay) InstanceURL() string {
|
||||
return r.instanceURL
|
||||
}
|
||||
|
||||
func (r *Relay) handshake(conn net.Conn) ([]byte, error) {
|
||||
buf := make([]byte, messages.MaxHandshakeSize)
|
||||
n, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
@@ -127,7 +156,3 @@ func (r *Relay) handShake(conn net.Conn) ([]byte, error) {
|
||||
}
|
||||
return peerID, nil
|
||||
}
|
||||
|
||||
func (r *Relay) InstanceURL() string {
|
||||
return r.instanceURL
|
||||
}
|
||||
|
||||
@@ -13,16 +13,27 @@ import (
|
||||
"github.com/netbirdio/netbird/relay/server/listener/ws"
|
||||
)
|
||||
|
||||
// ListenerConfig is the configuration for the listener.
|
||||
// Address: the address to bind the listener to. It could be an address behind a reverse proxy.
|
||||
// TLSConfig: the TLS configuration for the listener.
|
||||
type ListenerConfig struct {
|
||||
Address string
|
||||
TLSConfig *tls.Config
|
||||
}
|
||||
|
||||
// Server is the main entry point for the relay server.
|
||||
// It is the gate between the WebSocket listener and the Relay server logic.
|
||||
// In a new HTTP connection, the server will accept the connection and pass it to the Relay server via the Accept method.
|
||||
type Server struct {
|
||||
relay *Relay
|
||||
wSListener listener.Listener
|
||||
}
|
||||
|
||||
// NewServer creates a new relay server instance.
|
||||
// meter: the OpenTelemetry meter
|
||||
// exposedAddress: this address will be used as the instance URL. It should be a domain:port format.
|
||||
// tlsSupport: if true, the server will support TLS
|
||||
// authValidator: the auth validator to use for the server
|
||||
func NewServer(meter metric.Meter, exposedAddress string, tlsSupport bool, authValidator auth.Validator) (*Server, error) {
|
||||
relay, err := NewRelay(meter, exposedAddress, tlsSupport, authValidator)
|
||||
if err != nil {
|
||||
@@ -33,6 +44,7 @@ func NewServer(meter metric.Meter, exposedAddress string, tlsSupport bool, authV
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Listen starts the relay server.
|
||||
func (r *Server) Listen(cfg ListenerConfig) error {
|
||||
r.wSListener = &ws.Listener{
|
||||
Address: cfg.Address,
|
||||
@@ -47,6 +59,8 @@ func (r *Server) Listen(cfg ListenerConfig) error {
|
||||
return wslErr
|
||||
}
|
||||
|
||||
// Close stops the relay server. If there are active connections, they will be closed gracefully. In case of a timeout,
|
||||
// the connections will be forcefully closed.
|
||||
func (r *Server) Close() (err error) {
|
||||
// stop service new connections
|
||||
if r.wSListener != nil {
|
||||
@@ -60,6 +74,7 @@ func (r *Server) Close() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// InstanceURL returns the instance URL of the relay server.
|
||||
func (r *Server) InstanceURL() string {
|
||||
return r.relay.instanceURL
|
||||
}
|
||||
|
||||
@@ -4,29 +4,36 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Store is a thread-safe store of peers
|
||||
// It is used to store the peers that are connected to the relay server
|
||||
type Store struct {
|
||||
peers map[string]*Peer // consider to use [32]byte as key. The Peer(id string) would be faster
|
||||
peersLock sync.RWMutex
|
||||
}
|
||||
|
||||
// NewStore creates a new Store instance
|
||||
func NewStore() *Store {
|
||||
return &Store{
|
||||
peers: make(map[string]*Peer),
|
||||
}
|
||||
}
|
||||
|
||||
// AddPeer adds a peer to the store
|
||||
// It distinguishes the peers by their ID
|
||||
func (s *Store) AddPeer(peer *Peer) {
|
||||
s.peersLock.Lock()
|
||||
defer s.peersLock.Unlock()
|
||||
s.peers[peer.String()] = peer
|
||||
}
|
||||
|
||||
// DeletePeer deletes a peer from the store
|
||||
func (s *Store) DeletePeer(peer *Peer) {
|
||||
s.peersLock.Lock()
|
||||
defer s.peersLock.Unlock()
|
||||
delete(s.peers, peer.String())
|
||||
}
|
||||
|
||||
// Peer returns a peer by its ID
|
||||
func (s *Store) Peer(id string) (*Peer, bool) {
|
||||
s.peersLock.RLock()
|
||||
defer s.peersLock.RUnlock()
|
||||
@@ -35,6 +42,7 @@ func (s *Store) Peer(id string) (*Peer, bool) {
|
||||
return p, ok
|
||||
}
|
||||
|
||||
// Peers returns all the peers in the store
|
||||
func (s *Store) Peers() []*Peer {
|
||||
s.peersLock.RLock()
|
||||
defer s.peersLock.RUnlock()
|
||||
|
||||
Reference in New Issue
Block a user