mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-18 00:06:38 +00:00
142 lines
3.3 KiB
Go
142 lines
3.3 KiB
Go
//go:build js
|
|
|
|
package bind
|
|
|
|
import (
|
|
"net"
|
|
"net/netip"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"golang.zx2c4.com/wireguard/conn"
|
|
)
|
|
|
|
// GetICEMux returns a dummy UDP mux for WASM since browsers don't support UDP.
|
|
func (s *ICEBind) GetICEMux() (*UniversalUDPMuxDefault, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
// Open creates a receive function for handling relay packets in WASM.
|
|
func (s *ICEBind) Open(uport uint16) ([]conn.ReceiveFunc, uint16, error) {
|
|
log.Debugf("Open: creating receive function for port %d", uport)
|
|
|
|
s.closedMu.Lock()
|
|
s.closed = false
|
|
s.closedMu.Unlock()
|
|
|
|
if !s.receiverCreated {
|
|
s.receiverCreated = true
|
|
log.Debugf("Open: first call, setting receiverCreated=true")
|
|
}
|
|
|
|
receiveFn := func(bufs [][]byte, sizes []int, eps []conn.Endpoint) (int, error) {
|
|
s.closedMu.Lock()
|
|
if s.closed {
|
|
s.closedMu.Unlock()
|
|
return 0, net.ErrClosed
|
|
}
|
|
s.closedMu.Unlock()
|
|
|
|
msg, ok := <-s.RecvChan
|
|
if !ok {
|
|
return 0, net.ErrClosed
|
|
}
|
|
|
|
copy(bufs[0], msg.Buffer)
|
|
sizes[0] = len(msg.Buffer)
|
|
eps[0] = conn.Endpoint(msg.Endpoint)
|
|
return 1, nil
|
|
}
|
|
|
|
log.Debugf("Open: receive function created, returning port %d", uport)
|
|
return []conn.ReceiveFunc{receiveFn}, uport, nil
|
|
}
|
|
|
|
// SetMark is not applicable in WASM/browser environment.
|
|
func (s *ICEBind) SetMark(_ uint32) error {
|
|
return nil
|
|
}
|
|
|
|
// Send forwards packets through the relay connection for WASM.
|
|
func (s *ICEBind) Send(bufs [][]byte, ep conn.Endpoint) error {
|
|
if ep == nil {
|
|
return nil
|
|
}
|
|
|
|
fakeIP := ep.DstIP()
|
|
|
|
s.endpointsMu.Lock()
|
|
relayConn, ok := s.endpoints[fakeIP]
|
|
s.endpointsMu.Unlock()
|
|
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
for _, buf := range bufs {
|
|
if _, err := relayConn.Write(buf); err != nil {
|
|
log.Errorf("Send: failed to write to relay: %v", err)
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SetEndpoint stores a relay endpoint for a fake IP.
|
|
func (s *ICEBind) SetEndpoint(fakeIP netip.Addr, conn net.Conn) {
|
|
s.endpointsMu.Lock()
|
|
defer s.endpointsMu.Unlock()
|
|
|
|
if oldConn, exists := s.endpoints[fakeIP]; exists {
|
|
if oldConn != conn {
|
|
log.Debugf("SetEndpoint: replacing existing connection for %s", fakeIP)
|
|
if err := oldConn.Close(); err != nil {
|
|
log.Debugf("SetEndpoint: error closing old connection: %v", err)
|
|
}
|
|
s.endpoints[fakeIP] = conn
|
|
} else {
|
|
log.Tracef("SetEndpoint: same connection already set for %s, skipping", fakeIP)
|
|
}
|
|
} else {
|
|
log.Debugf("SetEndpoint: setting new relay connection for fake IP %s", fakeIP)
|
|
s.endpoints[fakeIP] = conn
|
|
}
|
|
}
|
|
|
|
// RemoveEndpoint removes a relay endpoint.
|
|
func (s *ICEBind) RemoveEndpoint(fakeIP netip.Addr) {
|
|
s.endpointsMu.Lock()
|
|
defer s.endpointsMu.Unlock()
|
|
delete(s.endpoints, fakeIP)
|
|
}
|
|
|
|
// BatchSize returns the batch size for WASM.
|
|
func (s *ICEBind) BatchSize() int {
|
|
return 1
|
|
}
|
|
|
|
// ParseEndpoint parses an endpoint string.
|
|
func (s *ICEBind) ParseEndpoint(s2 string) (conn.Endpoint, error) {
|
|
addrPort, err := netip.ParseAddrPort(s2)
|
|
if err != nil {
|
|
log.Errorf("ParseEndpoint: failed to parse %s: %v", s2, err)
|
|
return nil, err
|
|
}
|
|
ep := &Endpoint{AddrPort: addrPort}
|
|
return ep, nil
|
|
}
|
|
|
|
// Close closes the ICEBind.
|
|
func (s *ICEBind) Close() error {
|
|
log.Debugf("Close: closing ICEBind (receiverCreated=%v)", s.receiverCreated)
|
|
|
|
s.closedMu.Lock()
|
|
s.closed = true
|
|
s.closedMu.Unlock()
|
|
|
|
s.receiverCreated = false
|
|
|
|
log.Debugf("Close: returning from Close")
|
|
return nil
|
|
}
|