cmesh

package module
v1.9.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2025 License: MIT Imports: 58 Imported by: 0

README

What is Cmesh?

Cmesh is a scalable overlay networking tool with a focus on performance, simplicity and security. It lets you seamlessly connect computers anywhere in the world. Cmesh is portable, and runs on Linux, OSX, Windows, iOS, and Android. It can be used to connect a small number of computers, but is also able to connect tens of thousands of computers.

Cmesh incorporates a number of existing concepts like encryption, security groups, certificates, and tunneling, and each of those individual pieces existed before Cmesh in various forms. What makes Cmesh different to existing offerings is that it brings all of these ideas together, resulting in a sum that is greater than its individual parts.

Further documentation can be found here.

Supported Platforms

Desktop and Server

Check the releases page.

  • Linux - 64 and 32 bit, arm, and others
  • Windows
  • MacOS
  • Freebsd
Distribution Packages
Mobile

Technical Overview

Cmesh is a mutually authenticated peer-to-peer software defined network based on the Noise Protocol Framework. Cmesh uses certificates to assert a node's IP address, name, and membership within user-defined groups. Cmesh's user-defined groups allow for provider agnostic traffic filtering between nodes. Discovery nodes allow individual peers to find each other and optionally use UDP hole punching to establish connections from behind most firewalls or NATs. Users can move data between nodes in any number of cloud service providers, datacenters, and endpoints, without needing to maintain a particular addressing scheme.

Cmesh uses Elliptic-curve Diffie-Hellman (ECDH) key exchange and AES-256-GCM in its default configuration.

Cmesh was created to provide a mechanism for groups of hosts to communicate securely, even across the internet, while enabling expressive firewall definitions similar in style to cloud security groups.

Getting started (quickly)

To set up a Cmesh network, you'll need:

1. The Cmesh binaries or Distribution Packages for your specific platform. Specifically you'll need cmesh-cert and the specific cmesh binary for each platform you use.
2. (Optional, but you really should..) At least one discovery node with a routable IP address, which we call a lighthouse.

Cmesh lighthouses allow nodes to find each other, anywhere in the world. A lighthouse is the only node in a Cmesh network whose IP should not change. Running a lighthouse requires very few compute resources, and you can easily use the least expensive option from a cloud hosting provider. If you're not sure which provider to use, a number of us have used $5/mo DigitalOcean droplets as lighthouses.

Once you have launched an instance, ensure that Cmesh udp traffic (default port udp/4242) can reach it over the internet.

3. A Cmesh certificate authority, which will be the root of trust for a particular Cmesh network.
./cmesh-cert ca -name "Myorganization, Inc"

This will create files named ca.key and ca.cert in the current directory. The ca.key file is the most sensitive file you'll create, because it is the key used to sign the certificates for individual cmesh nodes/hosts. Please store this file somewhere safe, preferably with strong encryption.

4. Cmesh host keys and certificates generated from that certificate authority

This assumes you have four nodes, named lighthouse1, laptop, server1, host3. You can name the nodes any way you'd like, including FQDN. You'll also need to choose IP addresses and the associated subnet. In this example, we are creating a cmesh network that will use 192.168.100.x/24 as its network range. This example also demonstrates cmesh groups, which can later be used to define traffic rules in a cmesh network.

./cmesh-cert sign -name "lighthouse1" -ip "192.168.100.1/24"
./cmesh-cert sign -name "laptop" -ip "192.168.100.2/24" -groups "laptop,home,ssh"
./cmesh-cert sign -name "server1" -ip "192.168.100.9/24" -groups "servers"
./cmesh-cert sign -name "host3" -ip "192.168.100.10/24"
5. Configuration files for each host

Download a copy of the cmesh example configuration.

  • On the lighthouse node, you'll need to ensure am_lighthouse: true is set.

  • On the individual hosts, ensure the lighthouse is defined properly in the static_host_map section, and is added to the lighthouse hosts section.

6. Copy cmesh credentials, configuration, and binaries to each host

For each host, copy the cmesh binary to the host, along with config.yml from step 5, and the files ca.crt, {host}.crt, and {host}.key from step 4.

DO NOT COPY ca.key TO INDIVIDUAL NODES.

7. Run cmesh on each host
./cmesh -config /path/to/config.yml

Building Cmesh from source

Make sure you have go installed and clone this repo. Change to the cmesh directory.

To build cmesh for all platforms: make all

To build cmesh for a specific platform (ex, Windows): make bin-windows

See the Makefile for more details on build targets

Curve P256 and BoringCrypto

The default curve used for cryptographic handshakes and signatures is Curve25519. This is the recommended setting for most users. If your deployment has certain compliance requirements, you have the option of creating your CA using cmesh-cert ca -curve P256 to use NIST Curve P256. The CA will then sign certificates using ECDSA P256, and any hosts using these certificates will use P256 for ECDH handshakes.

In addition, Cmesh can be built using the BoringCrypto GOEXPERIMENT by running either of the following make targets:

make bin-boringcrypto
make release-boringcrypto

This is not the recommended default deployment, but may be useful based on your compliance requirements.

Credits

Cmesh is based on the Nebula, by CT129 Solutions.

(Nebula was created at Slack Technologies, Inc by Nate Brown and Ryan Huber, with contributions from Oliver Fross, Alan Lam, Wade Simmons, and Lining Wang).

Documentation

Index

Constants

View Source
const (
	DefaultHandshakeTryInterval   = time.Millisecond * 100
	DefaultHandshakeRetries       = 10
	DefaultHandshakeTriggerBuffer = 64
	DefaultUseRelays              = true
)
View Source
const (
	Requested = iota
	PeerRequested
	Established
	Disestablished
)
View Source
const (
	Unknowntype = iota
	ForwardingType
	TerminalType
)
View Source
const MaxHostInfosPerVpnIp = 5

MaxHostInfosPerVpnIp is the max number of hostinfos we will track for a given vpn ip 5 allows for an initial handshake and each host pair re-handshaking twice

View Source
const MaxRemotes = 10
View Source
const ReplayWindow = 1024
View Source
const RoamingSuppressSeconds = 2

How long we should prevent roaming back to the previous IP. This helps prevent flapping due to packets already in flight

Variables

View Source
var (
	ErrInvalidLengthCmesh        = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowCmesh          = fmt.Errorf("proto: integer overflow")
	ErrUnexpectedEndOfGroupCmesh = fmt.Errorf("proto: unexpected end of group")
)
View Source
var (
	ErrExistingHostInfo    = errors.New("existing hostinfo")
	ErrAlreadySeen         = errors.New("already seen")
	ErrLocalIndexCollision = errors.New("local index collision")
)
View Source
var (
	ErrPacketTooShort          = errors.New("packet is too short")
	ErrUnknownIPVersion        = errors.New("packet is an unknown ip version")
	ErrIPv4InvalidHeaderLength = errors.New("invalid ipv4 header length")
	ErrIPv4PacketTooShort      = errors.New("ipv4 packet is too short")
	ErrIPv6PacketTooShort      = errors.New("ipv6 packet is too short")
	ErrIPv6CouldNotFindPayload = errors.New("could not find payload in ipv6 packet")
)
View Source
var CmeshControl_MessageType_name = map[int32]string{
	0: "None",
	1: "CreateRelayRequest",
	2: "CreateRelayResponse",
}
View Source
var CmeshControl_MessageType_value = map[string]int32{
	"None":                0,
	"CreateRelayRequest":  1,
	"CreateRelayResponse": 2,
}
View Source
var CmeshMeta_MessageType_name = map[int32]string{
	0:  "None",
	1:  "HostQuery",
	2:  "HostQueryReply",
	3:  "HostUpdateNotification",
	4:  "HostMovedNotification",
	5:  "HostPunchNotification",
	6:  "HostWhoami",
	7:  "HostWhoamiReply",
	8:  "PathCheck",
	9:  "PathCheckReply",
	10: "HostUpdateNotificationAck",
}
View Source
var CmeshMeta_MessageType_value = map[string]int32{
	"None":                      0,
	"HostQuery":                 1,
	"HostQueryReply":            2,
	"HostUpdateNotification":    3,
	"HostMovedNotification":     4,
	"HostPunchNotification":     5,
	"HostWhoami":                6,
	"HostWhoamiReply":           7,
	"PathCheck":                 8,
	"PathCheckReply":            9,
	"HostUpdateNotificationAck": 10,
}
View Source
var CmeshPing_MessageType_name = map[int32]string{
	0: "Ping",
	1: "Reply",
}
View Source
var CmeshPing_MessageType_value = map[string]int32{
	"Ping":  0,
	"Reply": 1,
}
View Source
var ErrHostNotKnown = errors.New("host not known")
View Source
var ErrInvalidLocalIP = errors.New("local IP is not in list of handled local IPs")
View Source
var ErrInvalidRemoteIP = errors.New("remote IP is not in remote certificate subnets")
View Source
var ErrNoMatchingRule = errors.New("no matching rule in firewall table")

Functions

func AddFirewallRulesFromConfig

func AddFirewallRulesFromConfig(l *logrus.Logger, inbound bool, c *config.C, fw FirewallInterface) error

func AddRelay

func AddRelay(l *logrus.Logger, relayHostInfo *HostInfo, hm *HostMap, vpnIp netip.Addr, remoteIdx *uint32, relayType int, state int) (uint32, error)

AddRelay finds an available relay index on the hostmap, and associates the relay info with it. relayHostInfo is the Cmesh peer which can be used as a relay to access the target vpnIp.

func NewCalculatedRemotesFromConfig

func NewCalculatedRemotesFromConfig(c *config.C, k string) (*bart.Table[[]*calculatedRemote], error)

func NewHostnameResults

func NewHostnameResults(ctx context.Context, l *logrus.Logger, d time.Duration, network string, timeout time.Duration, hostPorts []string, onUpdate func()) (*hostnamesResults, error)

func NewRelayManager

func NewRelayManager(ctx context.Context, l *logrus.Logger, hostmap *HostMap, c *config.C) *relayManager

Types

type Addr

type Addr struct {
	Hi uint64 `protobuf:"varint,1,opt,name=Hi,proto3" json:"Hi,omitempty"`
	Lo uint64 `protobuf:"varint,2,opt,name=Lo,proto3" json:"Lo,omitempty"`
}

func (*Addr) Descriptor

func (*Addr) Descriptor() ([]byte, []int)

func (*Addr) GetHi

func (m *Addr) GetHi() uint64

func (*Addr) GetLo

func (m *Addr) GetLo() uint64

func (*Addr) Marshal

func (m *Addr) Marshal() (dAtA []byte, err error)

func (*Addr) MarshalTo

func (m *Addr) MarshalTo(dAtA []byte) (int, error)

func (*Addr) MarshalToSizedBuffer

func (m *Addr) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*Addr) ProtoMessage

func (*Addr) ProtoMessage()

func (*Addr) Reset

func (m *Addr) Reset()

func (*Addr) Size

func (m *Addr) Size() (n int)

func (*Addr) String

func (m *Addr) String() string

func (*Addr) Unmarshal

func (m *Addr) Unmarshal(dAtA []byte) error

func (*Addr) XXX_DiscardUnknown

func (m *Addr) XXX_DiscardUnknown()

func (*Addr) XXX_Marshal

func (m *Addr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Addr) XXX_Merge

func (m *Addr) XXX_Merge(src proto.Message)

func (*Addr) XXX_Size

func (m *Addr) XXX_Size() int

func (*Addr) XXX_Unmarshal

func (m *Addr) XXX_Unmarshal(b []byte) error

type AllowList

type AllowList struct {
	// contains filtered or unexported fields
}

func (*AllowList) Allow

func (al *AllowList) Allow(addr netip.Addr) bool

type AllowListNameRule

type AllowListNameRule struct {
	Name  *regexp.Regexp
	Allow bool
}

type Bits

type Bits struct {
	// contains filtered or unexported fields
}

func NewBits

func NewBits(bits uint64) *Bits

func (*Bits) Check

func (b *Bits) Check(l logrus.FieldLogger, i uint64) bool

func (*Bits) Update

func (b *Bits) Update(l *logrus.Logger, i uint64) bool

type Cache

type Cache struct {
	Learned  []netip.AddrPort `json:"learned,omitempty"`
	Reported []netip.AddrPort `json:"reported,omitempty"`
	Relay    []netip.Addr     `json:"relay"`
}

Cache is the other part of CacheMap to better represent the lighthouse cache for humans We don't reason about ipv4 vs ipv6 here

type CacheMap

type CacheMap map[string]*Cache

CacheMap is a struct that better represents the lighthouse cache for humans The string key is the owners vpnIp

type CertState

type CertState struct {
	// contains filtered or unexported fields
}

func (*CertState) GetDefaultCertificate

func (cs *CertState) GetDefaultCertificate() cert.Certificate

func (*CertState) MarshalJSON

func (cs *CertState) MarshalJSON() ([]byte, error)

func (*CertState) String

func (cs *CertState) String() string

type CmeshCipherState

type CmeshCipherState struct {
	// contains filtered or unexported fields
}

func NewCmeshCipherState

func NewCmeshCipherState(s *noise.CipherState) *CmeshCipherState

func (*CmeshCipherState) DecryptDanger

func (s *CmeshCipherState) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error)

func (*CmeshCipherState) EncryptDanger

func (s *CmeshCipherState) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error)

EncryptDanger encrypts and authenticates a given payload.

out is a destination slice to hold the output of the EncryptDanger operation.

  • ad is additional data, which will be authenticated and appended to out, but not encrypted.
  • plaintext is encrypted, authenticated and appended to out.
  • n is a nonce value which must never be re-used with this key.
  • nb is a buffer used for temporary storage in the implementation of this call, which should be re-used by callers to minimize garbage collection.

func (*CmeshCipherState) Overhead

func (s *CmeshCipherState) Overhead() int

type CmeshControl

type CmeshControl struct {
	Type                CmeshControl_MessageType `protobuf:"varint,1,opt,name=Type,proto3,enum=cmesh.CmeshControl_MessageType" json:"Type,omitempty"`
	InitiatorRelayIndex uint32                   `protobuf:"varint,2,opt,name=InitiatorRelayIndex,proto3" json:"InitiatorRelayIndex,omitempty"`
	ResponderRelayIndex uint32                   `protobuf:"varint,3,opt,name=ResponderRelayIndex,proto3" json:"ResponderRelayIndex,omitempty"`
	OldRelayToAddr      uint32                   `protobuf:"varint,4,opt,name=OldRelayToAddr,proto3" json:"OldRelayToAddr,omitempty"`     // Deprecated: Do not use.
	OldRelayFromAddr    uint32                   `protobuf:"varint,5,opt,name=OldRelayFromAddr,proto3" json:"OldRelayFromAddr,omitempty"` // Deprecated: Do not use.
	RelayToAddr         *Addr                    `protobuf:"bytes,6,opt,name=RelayToAddr,proto3" json:"RelayToAddr,omitempty"`
	RelayFromAddr       *Addr                    `protobuf:"bytes,7,opt,name=RelayFromAddr,proto3" json:"RelayFromAddr,omitempty"`
}

func (*CmeshControl) Descriptor

func (*CmeshControl) Descriptor() ([]byte, []int)

func (*CmeshControl) GetInitiatorRelayIndex

func (m *CmeshControl) GetInitiatorRelayIndex() uint32

func (*CmeshControl) GetOldRelayFromAddr deprecated

func (m *CmeshControl) GetOldRelayFromAddr() uint32

Deprecated: Do not use.

func (*CmeshControl) GetOldRelayToAddr deprecated

func (m *CmeshControl) GetOldRelayToAddr() uint32

Deprecated: Do not use.

func (*CmeshControl) GetRelayFromAddr

func (m *CmeshControl) GetRelayFromAddr() *Addr

func (*CmeshControl) GetRelayToAddr

func (m *CmeshControl) GetRelayToAddr() *Addr

func (*CmeshControl) GetResponderRelayIndex

func (m *CmeshControl) GetResponderRelayIndex() uint32

func (*CmeshControl) GetType

func (*CmeshControl) Marshal

func (m *CmeshControl) Marshal() (dAtA []byte, err error)

func (*CmeshControl) MarshalTo

func (m *CmeshControl) MarshalTo(dAtA []byte) (int, error)

func (*CmeshControl) MarshalToSizedBuffer

func (m *CmeshControl) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*CmeshControl) ProtoMessage

func (*CmeshControl) ProtoMessage()

func (*CmeshControl) Reset

func (m *CmeshControl) Reset()

func (*CmeshControl) Size

func (m *CmeshControl) Size() (n int)

func (*CmeshControl) String

func (m *CmeshControl) String() string

func (*CmeshControl) Unmarshal

func (m *CmeshControl) Unmarshal(dAtA []byte) error

func (*CmeshControl) XXX_DiscardUnknown

func (m *CmeshControl) XXX_DiscardUnknown()

func (*CmeshControl) XXX_Marshal

func (m *CmeshControl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*CmeshControl) XXX_Merge

func (m *CmeshControl) XXX_Merge(src proto.Message)

func (*CmeshControl) XXX_Size

func (m *CmeshControl) XXX_Size() int

func (*CmeshControl) XXX_Unmarshal

func (m *CmeshControl) XXX_Unmarshal(b []byte) error

type CmeshControl_MessageType

type CmeshControl_MessageType int32
const (
	CmeshControl_None                CmeshControl_MessageType = 0
	CmeshControl_CreateRelayRequest  CmeshControl_MessageType = 1
	CmeshControl_CreateRelayResponse CmeshControl_MessageType = 2
)

func (CmeshControl_MessageType) EnumDescriptor

func (CmeshControl_MessageType) EnumDescriptor() ([]byte, []int)

func (CmeshControl_MessageType) String

func (x CmeshControl_MessageType) String() string

type CmeshHandshake

type CmeshHandshake struct {
	Details *CmeshHandshakeDetails `protobuf:"bytes,1,opt,name=Details,proto3" json:"Details,omitempty"`
	Hmac    []byte                 `protobuf:"bytes,2,opt,name=Hmac,proto3" json:"Hmac,omitempty"`
}

func (*CmeshHandshake) Descriptor

func (*CmeshHandshake) Descriptor() ([]byte, []int)

func (*CmeshHandshake) GetDetails

func (m *CmeshHandshake) GetDetails() *CmeshHandshakeDetails

func (*CmeshHandshake) GetHmac

func (m *CmeshHandshake) GetHmac() []byte

func (*CmeshHandshake) Marshal

func (m *CmeshHandshake) Marshal() (dAtA []byte, err error)

func (*CmeshHandshake) MarshalTo

func (m *CmeshHandshake) MarshalTo(dAtA []byte) (int, error)

func (*CmeshHandshake) MarshalToSizedBuffer

func (m *CmeshHandshake) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*CmeshHandshake) ProtoMessage

func (*CmeshHandshake) ProtoMessage()

func (*CmeshHandshake) Reset

func (m *CmeshHandshake) Reset()

func (*CmeshHandshake) Size

func (m *CmeshHandshake) Size() (n int)

func (*CmeshHandshake) String

func (m *CmeshHandshake) String() string

func (*CmeshHandshake) Unmarshal

func (m *CmeshHandshake) Unmarshal(dAtA []byte) error

func (*CmeshHandshake) XXX_DiscardUnknown

func (m *CmeshHandshake) XXX_DiscardUnknown()

func (*CmeshHandshake) XXX_Marshal

func (m *CmeshHandshake) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*CmeshHandshake) XXX_Merge

func (m *CmeshHandshake) XXX_Merge(src proto.Message)

func (*CmeshHandshake) XXX_Size

func (m *CmeshHandshake) XXX_Size() int

func (*CmeshHandshake) XXX_Unmarshal

func (m *CmeshHandshake) XXX_Unmarshal(b []byte) error

type CmeshHandshakeDetails

type CmeshHandshakeDetails struct {
	Cert           []byte `protobuf:"bytes,1,opt,name=Cert,proto3" json:"Cert,omitempty"`
	InitiatorIndex uint32 `protobuf:"varint,2,opt,name=InitiatorIndex,proto3" json:"InitiatorIndex,omitempty"`
	ResponderIndex uint32 `protobuf:"varint,3,opt,name=ResponderIndex,proto3" json:"ResponderIndex,omitempty"`
	Cookie         uint64 `protobuf:"varint,4,opt,name=Cookie,proto3" json:"Cookie,omitempty"`
	Time           uint64 `protobuf:"varint,5,opt,name=Time,proto3" json:"Time,omitempty"`
	CertVersion    uint32 `protobuf:"varint,8,opt,name=CertVersion,proto3" json:"CertVersion,omitempty"`
}

func (*CmeshHandshakeDetails) Descriptor

func (*CmeshHandshakeDetails) Descriptor() ([]byte, []int)

func (*CmeshHandshakeDetails) GetCert

func (m *CmeshHandshakeDetails) GetCert() []byte

func (*CmeshHandshakeDetails) GetCertVersion

func (m *CmeshHandshakeDetails) GetCertVersion() uint32

func (*CmeshHandshakeDetails) GetCookie

func (m *CmeshHandshakeDetails) GetCookie() uint64

func (*CmeshHandshakeDetails) GetInitiatorIndex

func (m *CmeshHandshakeDetails) GetInitiatorIndex() uint32

func (*CmeshHandshakeDetails) GetResponderIndex

func (m *CmeshHandshakeDetails) GetResponderIndex() uint32

func (*CmeshHandshakeDetails) GetTime

func (m *CmeshHandshakeDetails) GetTime() uint64

func (*CmeshHandshakeDetails) Marshal

func (m *CmeshHandshakeDetails) Marshal() (dAtA []byte, err error)

func (*CmeshHandshakeDetails) MarshalTo

func (m *CmeshHandshakeDetails) MarshalTo(dAtA []byte) (int, error)

func (*CmeshHandshakeDetails) MarshalToSizedBuffer

func (m *CmeshHandshakeDetails) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*CmeshHandshakeDetails) ProtoMessage

func (*CmeshHandshakeDetails) ProtoMessage()

func (*CmeshHandshakeDetails) Reset

func (m *CmeshHandshakeDetails) Reset()

func (*CmeshHandshakeDetails) Size

func (m *CmeshHandshakeDetails) Size() (n int)

func (*CmeshHandshakeDetails) String

func (m *CmeshHandshakeDetails) String() string

func (*CmeshHandshakeDetails) Unmarshal

func (m *CmeshHandshakeDetails) Unmarshal(dAtA []byte) error

func (*CmeshHandshakeDetails) XXX_DiscardUnknown

func (m *CmeshHandshakeDetails) XXX_DiscardUnknown()

func (*CmeshHandshakeDetails) XXX_Marshal

func (m *CmeshHandshakeDetails) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*CmeshHandshakeDetails) XXX_Merge

func (m *CmeshHandshakeDetails) XXX_Merge(src proto.Message)

func (*CmeshHandshakeDetails) XXX_Size

func (m *CmeshHandshakeDetails) XXX_Size() int

func (*CmeshHandshakeDetails) XXX_Unmarshal

func (m *CmeshHandshakeDetails) XXX_Unmarshal(b []byte) error

type CmeshMeta

type CmeshMeta struct {
	Type    CmeshMeta_MessageType `protobuf:"varint,1,opt,name=Type,proto3,enum=cmesh.CmeshMeta_MessageType" json:"Type,omitempty"`
	Details *CmeshMetaDetails     `protobuf:"bytes,2,opt,name=Details,proto3" json:"Details,omitempty"`
}

func (*CmeshMeta) Descriptor

func (*CmeshMeta) Descriptor() ([]byte, []int)

func (*CmeshMeta) GetDetails

func (m *CmeshMeta) GetDetails() *CmeshMetaDetails

func (*CmeshMeta) GetType

func (m *CmeshMeta) GetType() CmeshMeta_MessageType

func (*CmeshMeta) Marshal

func (m *CmeshMeta) Marshal() (dAtA []byte, err error)

func (*CmeshMeta) MarshalTo

func (m *CmeshMeta) MarshalTo(dAtA []byte) (int, error)

func (*CmeshMeta) MarshalToSizedBuffer

func (m *CmeshMeta) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*CmeshMeta) ProtoMessage

func (*CmeshMeta) ProtoMessage()

func (*CmeshMeta) Reset

func (m *CmeshMeta) Reset()

func (*CmeshMeta) Size

func (m *CmeshMeta) Size() (n int)

func (*CmeshMeta) String

func (m *CmeshMeta) String() string

func (*CmeshMeta) Unmarshal

func (m *CmeshMeta) Unmarshal(dAtA []byte) error

func (*CmeshMeta) XXX_DiscardUnknown

func (m *CmeshMeta) XXX_DiscardUnknown()

func (*CmeshMeta) XXX_Marshal

func (m *CmeshMeta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*CmeshMeta) XXX_Merge

func (m *CmeshMeta) XXX_Merge(src proto.Message)

func (*CmeshMeta) XXX_Size

func (m *CmeshMeta) XXX_Size() int

func (*CmeshMeta) XXX_Unmarshal

func (m *CmeshMeta) XXX_Unmarshal(b []byte) error

type CmeshMetaDetails

type CmeshMetaDetails struct {
	OldVpnAddr       uint32        `protobuf:"varint,1,opt,name=OldVpnAddr,proto3" json:"OldVpnAddr,omitempty"` // Deprecated: Do not use.
	VpnAddr          *Addr         `protobuf:"bytes,6,opt,name=VpnAddr,proto3" json:"VpnAddr,omitempty"`
	OldRelayVpnAddrs []uint32      `protobuf:"varint,5,rep,packed,name=OldRelayVpnAddrs,proto3" json:"OldRelayVpnAddrs,omitempty"` // Deprecated: Do not use.
	RelayVpnAddrs    []*Addr       `protobuf:"bytes,7,rep,name=RelayVpnAddrs,proto3" json:"RelayVpnAddrs,omitempty"`
	V4AddrPorts      []*V4AddrPort `protobuf:"bytes,2,rep,name=V4AddrPorts,proto3" json:"V4AddrPorts,omitempty"`
	V6AddrPorts      []*V6AddrPort `protobuf:"bytes,4,rep,name=V6AddrPorts,proto3" json:"V6AddrPorts,omitempty"`
	Counter          uint32        `protobuf:"varint,3,opt,name=counter,proto3" json:"counter,omitempty"`
}

func (*CmeshMetaDetails) Descriptor

func (*CmeshMetaDetails) Descriptor() ([]byte, []int)

func (*CmeshMetaDetails) GetCounter

func (m *CmeshMetaDetails) GetCounter() uint32

func (*CmeshMetaDetails) GetOldRelayVpnAddrs deprecated

func (m *CmeshMetaDetails) GetOldRelayVpnAddrs() []uint32

Deprecated: Do not use.

func (*CmeshMetaDetails) GetOldVpnAddr deprecated

func (m *CmeshMetaDetails) GetOldVpnAddr() uint32

Deprecated: Do not use.

func (*CmeshMetaDetails) GetRelayVpnAddrs

func (m *CmeshMetaDetails) GetRelayVpnAddrs() []*Addr

func (*CmeshMetaDetails) GetRelays

func (d *CmeshMetaDetails) GetRelays() []netip.Addr

func (*CmeshMetaDetails) GetV4AddrPorts

func (m *CmeshMetaDetails) GetV4AddrPorts() []*V4AddrPort

func (*CmeshMetaDetails) GetV6AddrPorts

func (m *CmeshMetaDetails) GetV6AddrPorts() []*V6AddrPort

func (*CmeshMetaDetails) GetVpnAddr

func (m *CmeshMetaDetails) GetVpnAddr() *Addr

func (*CmeshMetaDetails) Marshal

func (m *CmeshMetaDetails) Marshal() (dAtA []byte, err error)

func (*CmeshMetaDetails) MarshalTo

func (m *CmeshMetaDetails) MarshalTo(dAtA []byte) (int, error)

func (*CmeshMetaDetails) MarshalToSizedBuffer

func (m *CmeshMetaDetails) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*CmeshMetaDetails) ProtoMessage

func (*CmeshMetaDetails) ProtoMessage()

func (*CmeshMetaDetails) Reset

func (m *CmeshMetaDetails) Reset()

func (*CmeshMetaDetails) Size

func (m *CmeshMetaDetails) Size() (n int)

func (*CmeshMetaDetails) String

func (m *CmeshMetaDetails) String() string

func (*CmeshMetaDetails) Unmarshal

func (m *CmeshMetaDetails) Unmarshal(dAtA []byte) error

func (*CmeshMetaDetails) XXX_DiscardUnknown

func (m *CmeshMetaDetails) XXX_DiscardUnknown()

func (*CmeshMetaDetails) XXX_Marshal

func (m *CmeshMetaDetails) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*CmeshMetaDetails) XXX_Merge

func (m *CmeshMetaDetails) XXX_Merge(src proto.Message)

func (*CmeshMetaDetails) XXX_Size

func (m *CmeshMetaDetails) XXX_Size() int

func (*CmeshMetaDetails) XXX_Unmarshal

func (m *CmeshMetaDetails) XXX_Unmarshal(b []byte) error

type CmeshMeta_MessageType

type CmeshMeta_MessageType int32
const (
	CmeshMeta_None                      CmeshMeta_MessageType = 0
	CmeshMeta_HostQuery                 CmeshMeta_MessageType = 1
	CmeshMeta_HostQueryReply            CmeshMeta_MessageType = 2
	CmeshMeta_HostUpdateNotification    CmeshMeta_MessageType = 3
	CmeshMeta_HostMovedNotification     CmeshMeta_MessageType = 4
	CmeshMeta_HostPunchNotification     CmeshMeta_MessageType = 5
	CmeshMeta_HostWhoami                CmeshMeta_MessageType = 6
	CmeshMeta_HostWhoamiReply           CmeshMeta_MessageType = 7
	CmeshMeta_PathCheck                 CmeshMeta_MessageType = 8
	CmeshMeta_PathCheckReply            CmeshMeta_MessageType = 9
	CmeshMeta_HostUpdateNotificationAck CmeshMeta_MessageType = 10
)

func (CmeshMeta_MessageType) EnumDescriptor

func (CmeshMeta_MessageType) EnumDescriptor() ([]byte, []int)

func (CmeshMeta_MessageType) String

func (x CmeshMeta_MessageType) String() string

type CmeshPing

type CmeshPing struct {
	Type CmeshPing_MessageType `protobuf:"varint,1,opt,name=Type,proto3,enum=cmesh.CmeshPing_MessageType" json:"Type,omitempty"`
	Time uint64                `protobuf:"varint,2,opt,name=Time,proto3" json:"Time,omitempty"`
}

func (*CmeshPing) Descriptor

func (*CmeshPing) Descriptor() ([]byte, []int)

func (*CmeshPing) GetTime

func (m *CmeshPing) GetTime() uint64

func (*CmeshPing) GetType

func (m *CmeshPing) GetType() CmeshPing_MessageType

func (*CmeshPing) Marshal

func (m *CmeshPing) Marshal() (dAtA []byte, err error)

func (*CmeshPing) MarshalTo

func (m *CmeshPing) MarshalTo(dAtA []byte) (int, error)

func (*CmeshPing) MarshalToSizedBuffer

func (m *CmeshPing) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*CmeshPing) ProtoMessage

func (*CmeshPing) ProtoMessage()

func (*CmeshPing) Reset

func (m *CmeshPing) Reset()

func (*CmeshPing) Size

func (m *CmeshPing) Size() (n int)

func (*CmeshPing) String

func (m *CmeshPing) String() string

func (*CmeshPing) Unmarshal

func (m *CmeshPing) Unmarshal(dAtA []byte) error

func (*CmeshPing) XXX_DiscardUnknown

func (m *CmeshPing) XXX_DiscardUnknown()

func (*CmeshPing) XXX_Marshal

func (m *CmeshPing) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*CmeshPing) XXX_Merge

func (m *CmeshPing) XXX_Merge(src proto.Message)

func (*CmeshPing) XXX_Size

func (m *CmeshPing) XXX_Size() int

func (*CmeshPing) XXX_Unmarshal

func (m *CmeshPing) XXX_Unmarshal(b []byte) error

type CmeshPing_MessageType

type CmeshPing_MessageType int32
const (
	CmeshPing_Ping  CmeshPing_MessageType = 0
	CmeshPing_Reply CmeshPing_MessageType = 1
)

func (CmeshPing_MessageType) EnumDescriptor

func (CmeshPing_MessageType) EnumDescriptor() ([]byte, []int)

func (CmeshPing_MessageType) String

func (x CmeshPing_MessageType) String() string

type ConnectionState

type ConnectionState struct {
	H *noise.HandshakeState
	// contains filtered or unexported fields
}

func NewConnectionState

func NewConnectionState(l *logrus.Logger, cs *CertState, crt cert.Certificate, initiator bool, pattern noise.HandshakePattern) (*ConnectionState, error)

func (*ConnectionState) Curve

func (cs *ConnectionState) Curve() cert.Curve

func (*ConnectionState) MarshalJSON

func (cs *ConnectionState) MarshalJSON() ([]byte, error)

type Control

type Control struct {
	// contains filtered or unexported fields
}

func Main

func Main(c *config.C, configTest bool, buildVersion string, logger *logrus.Logger, deviceFactory overlay.DeviceFactory) (retcon *Control, reterr error)

func (*Control) CloseAllTunnels

func (c *Control) CloseAllTunnels(excludeLighthouses bool) (closed int)

CloseAllTunnels is just like CloseTunnel except it goes through and shuts them all down, optionally you can avoid shutting down lighthouse tunnels the int returned is a count of tunnels closed

func (*Control) CloseTunnel

func (c *Control) CloseTunnel(vpnIp netip.Addr, localOnly bool) bool

CloseTunnel closes a fully established tunnel. If localOnly is false it will notify the remote end as well. Caller should take care to Unmap() any 4in6 addresses prior to calling.

func (*Control) Context

func (c *Control) Context() context.Context

func (*Control) CreateTunnel

func (c *Control) CreateTunnel(vpnIp netip.Addr)

CreateTunnel creates a new tunnel to the given vpn ip.

func (*Control) Device

func (c *Control) Device() overlay.Device

func (*Control) GetCertByVpnIp

func (c *Control) GetCertByVpnIp(vpnIp netip.Addr) cert.Certificate

GetCertByVpnIp returns the authenticated certificate of the given vpn IP, or nil if not found

func (*Control) GetHostInfoByVpnAddr

func (c *Control) GetHostInfoByVpnAddr(vpnAddr netip.Addr, pending bool) *ControlHostInfo

GetHostInfoByVpnAddr returns a single tunnels hostInfo, or nil if not found Caller should take care to Unmap() any 4in6 addresses prior to calling.

func (*Control) ListHostmapHosts

func (c *Control) ListHostmapHosts(pendingMap bool) []ControlHostInfo

ListHostmapHosts returns details about the actual or pending (handshaking) hostmap by vpn ip

func (*Control) ListHostmapIndexes

func (c *Control) ListHostmapIndexes(pendingMap bool) []ControlHostInfo

ListHostmapIndexes returns details about the actual or pending (handshaking) hostmap by local index id

func (*Control) PrintTunnel

func (c *Control) PrintTunnel(vpnIp netip.Addr) *ControlHostInfo

PrintTunnel creates a new tunnel to the given vpn ip.

func (*Control) QueryLighthouse

func (c *Control) QueryLighthouse(vpnIp netip.Addr) *CacheMap

QueryLighthouse queries the lighthouse.

func (*Control) RebindUDPServer

func (c *Control) RebindUDPServer()

RebindUDPServer asks the UDP listener to rebind it's listener. Mainly used on mobile clients when interfaces change

func (*Control) SetRemoteForTunnel

func (c *Control) SetRemoteForTunnel(vpnIp netip.Addr, addr netip.AddrPort) *ControlHostInfo

SetRemoteForTunnel forces a tunnel to use a specific remote Caller should take care to Unmap() any 4in6 addresses prior to calling.

func (*Control) ShutdownBlock

func (c *Control) ShutdownBlock()

ShutdownBlock will listen for and block on term and interrupt signals, calling Control.Stop() once signalled

func (*Control) Start

func (c *Control) Start()

Start actually runs cmesh, this is a nonblocking call. To block use Control.ShutdownBlock()

func (*Control) Stop

func (c *Control) Stop()

Stop signals cmesh to shutdown and close all tunnels, returns after the shutdown is complete

type ControlHostInfo

type ControlHostInfo struct {
	VpnAddrs               []netip.Addr     `json:"vpnAddrs"`
	LocalIndex             uint32           `json:"localIndex"`
	RemoteIndex            uint32           `json:"remoteIndex"`
	RemoteAddrs            []netip.AddrPort `json:"remoteAddrs"`
	Cert                   cert.Certificate `json:"cert"`
	MessageCounter         uint64           `json:"messageCounter"`
	CurrentRemote          netip.AddrPort   `json:"currentRemote"`
	CurrentRelaysToMe      []netip.Addr     `json:"currentRelaysToMe"`
	CurrentRelaysThroughMe []netip.Addr     `json:"currentRelaysThroughMe"`
}

type EncWriter

type EncWriter interface {
	SendVia(via *HostInfo,
		relay *Relay,
		ad,
		nb,
		out []byte,
		nocopy bool,
	)
	SendMessageToVpnAddr(t header.MessageType, st header.MessageSubType, vpnAddr netip.Addr, p, nb, out []byte)
	SendMessageToHostInfo(t header.MessageType, st header.MessageSubType, hostinfo *HostInfo, p, nb, out []byte)
	Handshake(vpnAddr netip.Addr)
	GetHostInfo(vpnAddr netip.Addr) *HostInfo
	GetCertState() *CertState
}

type Firewall

type Firewall struct {
	Conntrack *FirewallConntrack

	InRules  *FirewallTable
	OutRules *FirewallTable

	InSendReject  bool
	OutSendReject bool

	//TODO: we should have many more options for TCP, an option for ICMP, and mimic the kernel a bit better
	// https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt
	TCPTimeout     time.Duration //linux: 5 days max
	UDPTimeout     time.Duration //linux: 180s max
	DefaultTimeout time.Duration //linux: 600s
	// contains filtered or unexported fields
}

TODO: need conntrack max tracked connections handling

func NewFirewall

func NewFirewall(l *logrus.Logger, tcpTimeout, UDPTimeout, defaultTimeout time.Duration, c cert.Certificate) *Firewall

NewFirewall creates a new Firewall object. A TimerWheel is created for you from the provided timeouts. The certificate provided should be the highest version loaded in memory.

func NewFirewallFromConfig

func NewFirewallFromConfig(l *logrus.Logger, cs *CertState, c *config.C) (*Firewall, error)

func (*Firewall) AddRule

func (f *Firewall) AddRule(incoming bool, proto uint8, startPort int32, endPort int32, groups []string, host string, ip, localIp netip.Prefix, caName string, caSha string) error

AddRule properly creates the in memory rule structure for a firewall table.

func (*Firewall) Destroy

func (f *Firewall) Destroy()

Destroy cleans up any known cyclical references so the object can be free'd my GC. This should be called if a new firewall object is created

func (*Firewall) Drop

func (f *Firewall) Drop(fp firewall.Packet, incoming bool, h *HostInfo, caPool *cert.CAPool, localCache firewall.ConntrackCache) error

Drop returns an error if the packet should be dropped, explaining why. It returns nil if the packet should not be dropped.

func (*Firewall) EmitStats

func (f *Firewall) EmitStats()

func (*Firewall) GetRuleHash

func (f *Firewall) GetRuleHash() string

GetRuleHash returns a hash representation of all inbound and outbound rules

func (*Firewall) GetRuleHashFNV

func (f *Firewall) GetRuleHashFNV() uint32

GetRuleHashFNV returns a uint32 FNV-1 hash representation the rules, for use as a metric value

func (*Firewall) GetRuleHashes

func (f *Firewall) GetRuleHashes() string

GetRuleHashes returns both the sha256 and FNV-1 hashes, suitable for logging

type FirewallCA

type FirewallCA struct {
	Any     *FirewallRule
	CANames map[string]*FirewallRule
	CAShas  map[string]*FirewallRule
}

type FirewallConntrack

type FirewallConntrack struct {
	sync.Mutex

	Conns      map[firewall.Packet]*conn
	TimerWheel *TimerWheel[firewall.Packet]
}

type FirewallInterface

type FirewallInterface interface {
	AddRule(incoming bool, proto uint8, startPort int32, endPort int32, groups []string, host string, addr, localAddr netip.Prefix, caName string, caSha string) error
}

type FirewallRule

type FirewallRule struct {
	// Any makes Hosts, Groups, and CIDR irrelevant
	Any    *firewallLocalCIDR
	Hosts  map[string]*firewallLocalCIDR
	Groups []*firewallGroups
	CIDR   *bart.Table[*firewallLocalCIDR]
}

type FirewallTable

type FirewallTable struct {
	TCP      firewallPort
	UDP      firewallPort
	ICMP     firewallPort
	AnyProto firewallPort
}

FirewallTable is the entry point for a rule, the evaluation order is: Proto AND port AND (CA SHA or CA name) AND local CIDR AND (group OR groups OR name OR remote CIDR)

type HandshakeConfig

type HandshakeConfig struct {
	// contains filtered or unexported fields
}

type HandshakeHostInfo

type HandshakeHostInfo struct {
	sync.Mutex
	// contains filtered or unexported fields
}

type HandshakeManager

type HandshakeManager struct {
	// Mutex for interacting with the vpnIps and indexes maps
	sync.RWMutex

	OutboundHandshakeTimer *LockingTimerWheel[netip.Addr]
	// contains filtered or unexported fields
}

func NewHandshakeManager

func NewHandshakeManager(l *logrus.Logger, mainHostMap *HostMap, lightHouse *LightHouse, outside udp.Conn, config HandshakeConfig) *HandshakeManager

func (*HandshakeManager) CheckAndComplete

func (hm *HandshakeManager) CheckAndComplete(hostinfo *HostInfo, handshakePacket uint8, f *Interface) (*HostInfo, error)

CheckAndComplete checks for any conflicts in the main and pending hostmap before adding hostinfo to main. If err is nil, it was added. Otherwise err will be:

ErrAlreadySeen if we already have an entry in the hostmap that has seen the exact same handshake packet

ErrExistingHostInfo if we already have an entry in the hostmap for this VpnIp and the new handshake was older than the one we currently have

ErrLocalIndexCollision if we already have an entry in the main or pending hostmap for the hostinfo.localIndexId.

func (*HandshakeManager) Complete

func (hm *HandshakeManager) Complete(hostinfo *HostInfo, f *Interface)

Complete is a simpler version of CheckAndComplete when we already know we won't have a localIndexId collision because we already have an entry in the pendingHostMap. An existing hostinfo is returned if there was one.

func (*HandshakeManager) DeleteHostInfo

func (hm *HandshakeManager) DeleteHostInfo(hostinfo *HostInfo)

func (*HandshakeManager) EmitStats

func (hm *HandshakeManager) EmitStats()

func (*HandshakeManager) ForEachIndex

func (hm *HandshakeManager) ForEachIndex(f controlEach)

func (*HandshakeManager) ForEachVpnAddr

func (hm *HandshakeManager) ForEachVpnAddr(f controlEach)

func (*HandshakeManager) GetOrHandshake

func (hm *HandshakeManager) GetOrHandshake(vpnIp netip.Addr, cacheCb func(*HandshakeHostInfo)) (*HostInfo, bool)

GetOrHandshake will try to find a hostinfo with a fully formed tunnel or start a new handshake if one is not present The 2nd argument will be true if the hostinfo is ready to transmit traffic

func (*HandshakeManager) GetPreferredRanges

func (hm *HandshakeManager) GetPreferredRanges() []netip.Prefix

func (*HandshakeManager) HandleIncoming

func (hm *HandshakeManager) HandleIncoming(addr netip.AddrPort, via *ViaSender, packet []byte, h *header.H)

func (*HandshakeManager) NextOutboundHandshakeTimerTick

func (hm *HandshakeManager) NextOutboundHandshakeTimerTick(now time.Time)

func (*HandshakeManager) QueryIndex

func (hm *HandshakeManager) QueryIndex(index uint32) *HostInfo

func (*HandshakeManager) QueryVpnAddr

func (hm *HandshakeManager) QueryVpnAddr(vpnIp netip.Addr) *HostInfo

func (*HandshakeManager) Run

func (hm *HandshakeManager) Run(ctx context.Context)

func (*HandshakeManager) StartHandshake

func (hm *HandshakeManager) StartHandshake(vpnAddr netip.Addr, cacheCb func(*HandshakeHostInfo)) *HostInfo

StartHandshake will ensure a handshake is currently being attempted for the provided vpn ip

type HostInfo

type HostInfo struct {
	ConnectionState *ConnectionState

	// HandshakePacket records the packets used to create this hostinfo
	// We need these to avoid replayed handshake packets creating new hostinfos which causes churn
	HandshakePacket map[uint8][]byte
	// contains filtered or unexported fields
}

func (*HostInfo) GetCert

func (i *HostInfo) GetCert() *cert.CachedCertificate

func (*HostInfo) RecvErrorExceeded

func (i *HostInfo) RecvErrorExceeded() bool

func (*HostInfo) SetRemote

func (i *HostInfo) SetRemote(remote netip.AddrPort)

func (*HostInfo) SetRemoteIfPreferred

func (i *HostInfo) SetRemoteIfPreferred(hm *HostMap, newRemote netip.AddrPort) bool

SetRemoteIfPreferred returns true if the remote was changed. The lastRoam time on the HostInfo will also be updated.

func (*HostInfo) TryPromoteBest

func (i *HostInfo) TryPromoteBest(preferredRanges []netip.Prefix, ifce *Interface)

TryPromoteBest handles re-querying lighthouses and probing for better paths NOTE: It is an error to call this if you are a lighthouse since they should not roam clients!

type HostMap

type HostMap struct {
	sync.RWMutex  //Because we concurrently read and write to our maps
	Indexes       map[uint32]*HostInfo
	Relays        map[uint32]*HostInfo // Maps a Relay IDX to a Relay HostInfo object
	RemoteIndexes map[uint32]*HostInfo
	Hosts         map[netip.Addr]*HostInfo
	// contains filtered or unexported fields
}

func NewHostMapFromConfig

func NewHostMapFromConfig(l *logrus.Logger, c *config.C) *HostMap

func (*HostMap) DeleteHostInfo

func (hm *HostMap) DeleteHostInfo(hostinfo *HostInfo) bool

DeleteHostInfo will fully unlink the hostinfo and return true if it was the final hostinfo for this vpn ip

func (*HostMap) EmitStats

func (hm *HostMap) EmitStats()

EmitStats reports host, index, and relay counts to the stats collection system

func (*HostMap) ForEachIndex

func (hm *HostMap) ForEachIndex(f controlEach)

func (*HostMap) ForEachVpnAddr

func (hm *HostMap) ForEachVpnAddr(f controlEach)

func (*HostMap) GetPreferredRanges

func (hm *HostMap) GetPreferredRanges() []netip.Prefix

func (*HostMap) MakePrimary

func (hm *HostMap) MakePrimary(hostinfo *HostInfo)

func (*HostMap) QueryIndex

func (hm *HostMap) QueryIndex(index uint32) *HostInfo

func (*HostMap) QueryRelayIndex

func (hm *HostMap) QueryRelayIndex(index uint32) *HostInfo

func (*HostMap) QueryReverseIndex

func (hm *HostMap) QueryReverseIndex(index uint32) *HostInfo

func (*HostMap) QueryVpnAddr

func (hm *HostMap) QueryVpnAddr(vpnIp netip.Addr) *HostInfo

func (*HostMap) QueryVpnAddrsRelayFor

func (hm *HostMap) QueryVpnAddrsRelayFor(targetIps []netip.Addr, relayHostIp netip.Addr) (*HostInfo, *Relay, error)

type Interface

type Interface struct {
	// contains filtered or unexported fields
}

func NewInterface

func NewInterface(ctx context.Context, c *InterfaceConfig) (*Interface, error)

func (*Interface) Close

func (f *Interface) Close() error

func (*Interface) GetCertState

func (f *Interface) GetCertState() *CertState

func (*Interface) GetHostInfo

func (f *Interface) GetHostInfo(vpnIp netip.Addr) *HostInfo

func (*Interface) Handshake

func (f *Interface) Handshake(vpnAddr netip.Addr)

Handshake will attempt to initiate a tunnel with the provided vpn address if it is within our vpn networks. This is a no-op if the tunnel is already established or being established

func (*Interface) RegisterConfigChangeCallbacks

func (f *Interface) RegisterConfigChangeCallbacks(c *config.C)

func (*Interface) SendMessageToHostInfo

func (f *Interface) SendMessageToHostInfo(t header.MessageType, st header.MessageSubType, hi *HostInfo, p, nb, out []byte)

func (*Interface) SendMessageToVpnAddr

func (f *Interface) SendMessageToVpnAddr(t header.MessageType, st header.MessageSubType, vpnAddr netip.Addr, p, nb, out []byte)

SendMessageToVpnAddr handles real addr:port lookup and sends to the current best known address for vpnAddr

func (*Interface) SendVia

func (f *Interface) SendVia(via *HostInfo,
	relay *Relay,
	ad,
	nb,
	out []byte,
	nocopy bool,
)

SendVia sends a payload through a Relay tunnel. No authentication or encryption is done to the payload for the ultimate target host, making this a useful method for sending handshake messages to peers through relay tunnels. via is the HostInfo through which the message is relayed. ad is the plaintext data to authenticate, but not encrypt nb is a buffer used to store the nonce value, re-used for performance reasons. out is a buffer used to store the result of the Encrypt operation q indicates which writer to use to send the packet.

type InterfaceConfig

type InterfaceConfig struct {
	HostMap *HostMap
	Outside udp.Conn
	Inside  overlay.Device

	Firewall         *Firewall
	ServeDns         bool
	HandshakeManager *HandshakeManager

	DropLocalBroadcast bool
	DropMulticast      bool

	MessageMetrics *MessageMetrics

	ConntrackCacheTimeout time.Duration
	// contains filtered or unexported fields
}

type LightHouse

type LightHouse struct {
	//TODO: We need a timer wheel to kick out vpnAddrs that haven't reported in a long time
	sync.RWMutex //Because we concurrently read and write to our maps
	// contains filtered or unexported fields
}

func NewLightHouseFromConfig

func NewLightHouseFromConfig(ctx context.Context, l *logrus.Logger, c *config.C, cs *CertState, pc udp.Conn, p *Punchy) (*LightHouse, error)

NewLightHouseFromConfig will build a Lighthouse struct from the values provided in the config object addrMap should be nil unless this is during a config reload

func (*LightHouse) DeleteVpnAddrs

func (lh *LightHouse) DeleteVpnAddrs(allVpnAddrs []netip.Addr)

func (*LightHouse) GetAdvertiseAddrs

func (lh *LightHouse) GetAdvertiseAddrs() []netip.AddrPort

func (*LightHouse) GetLighthouses

func (lh *LightHouse) GetLighthouses() map[netip.Addr]struct{}

func (*LightHouse) GetLocalAllowList

func (lh *LightHouse) GetLocalAllowList() *LocalAllowList

func (*LightHouse) GetRelaysForMe

func (lh *LightHouse) GetRelaysForMe() []netip.Addr

func (*LightHouse) GetRemoteAllowList

func (lh *LightHouse) GetRemoteAllowList() *RemoteAllowList

func (*LightHouse) GetStaticHostList

func (lh *LightHouse) GetStaticHostList() map[netip.Addr]struct{}

func (*LightHouse) GetUpdateInterval

func (lh *LightHouse) GetUpdateInterval() int64

func (*LightHouse) IsAnyLighthouseAddr

func (lh *LightHouse) IsAnyLighthouseAddr(vpnAddr []netip.Addr) bool

TODO: CERT-V2 IsLighthouseAddr should be sufficient, we just need to update the vpnAddrs for lighthouses after a handshake so that we know all the lighthouse vpnAddrs, not just the ones we were configured to talk to initially

func (*LightHouse) IsLighthouseAddr

func (lh *LightHouse) IsLighthouseAddr(vpnAddr netip.Addr) bool

func (*LightHouse) NewRequestHandler

func (lh *LightHouse) NewRequestHandler() *LightHouseHandler

func (*LightHouse) Query

func (lh *LightHouse) Query(vpnAddr netip.Addr) *RemoteList

func (*LightHouse) QueryCache

func (lh *LightHouse) QueryCache(vpnAddrs []netip.Addr) *RemoteList

func (*LightHouse) QueryServer

func (lh *LightHouse) QueryServer(vpnAddr netip.Addr)

QueryServer is asynchronous so no reply should be expected

func (*LightHouse) SendUpdate

func (lh *LightHouse) SendUpdate()

func (*LightHouse) StartUpdateWorker

func (lh *LightHouse) StartUpdateWorker()

type LightHouseHandler

type LightHouseHandler struct {
	// contains filtered or unexported fields
}

func (*LightHouseHandler) HandleRequest

func (lhh *LightHouseHandler) HandleRequest(rAddr netip.AddrPort, fromVpnAddrs []netip.Addr, p []byte, w EncWriter)

type LocalAllowList

type LocalAllowList struct {
	AllowList *AllowList
	// contains filtered or unexported fields
}

func NewLocalAllowListFromConfig

func NewLocalAllowListFromConfig(c *config.C, k string) (*LocalAllowList, error)

func (*LocalAllowList) Allow

func (al *LocalAllowList) Allow(udpAddr netip.Addr) bool

func (*LocalAllowList) AllowName

func (al *LocalAllowList) AllowName(name string) bool

type LockingTimerWheel

type LockingTimerWheel[T any] struct {
	// contains filtered or unexported fields
}

func NewLockingTimerWheel

func NewLockingTimerWheel[T any](min, max time.Duration) *LockingTimerWheel[T]

NewLockingTimerWheel is version of TimerWheel that is safe for concurrent use with a small performance penalty

func (*LockingTimerWheel[T]) Add

func (lw *LockingTimerWheel[T]) Add(v T, timeout time.Duration) *TimeoutItem[T]

func (*LockingTimerWheel[T]) Advance

func (lw *LockingTimerWheel[T]) Advance(now time.Time)

func (*LockingTimerWheel[T]) Purge

func (lw *LockingTimerWheel[T]) Purge() (T, bool)

type MessageMetrics

type MessageMetrics struct {
	// contains filtered or unexported fields
}

func (*MessageMetrics) Rx

func (*MessageMetrics) Tx

type PKI

type PKI struct {
	// contains filtered or unexported fields
}

func NewPKIFromConfig

func NewPKIFromConfig(l *logrus.Logger, c *config.C) (*PKI, error)

func (*PKI) GetCAPool

func (p *PKI) GetCAPool() *cert.CAPool

type Punchy

type Punchy struct {
	// contains filtered or unexported fields
}

func NewPunchyFromConfig

func NewPunchyFromConfig(l *logrus.Logger, c *config.C) *Punchy

func (*Punchy) GetDelay

func (p *Punchy) GetDelay() time.Duration

func (*Punchy) GetPunch

func (p *Punchy) GetPunch() bool

func (*Punchy) GetRespond

func (p *Punchy) GetRespond() bool

func (*Punchy) GetRespondDelay

func (p *Punchy) GetRespondDelay() time.Duration

func (*Punchy) GetTargetEverything

func (p *Punchy) GetTargetEverything() bool

type Relay

type Relay struct {
	Type        int
	State       int
	LocalIndex  uint32
	RemoteIndex uint32
	PeerAddr    netip.Addr
}

type RelayState

type RelayState struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

For synchronization, treat the pointed-to Relay struct as immutable. To edit the Relay struct, make a copy of an existing value, edit the fileds in the copy, and then store a pointer to the new copy in both realyForBy* maps.

func (*RelayState) CompleteRelayByIP

func (rs *RelayState) CompleteRelayByIP(vpnIp netip.Addr, remoteIdx uint32) bool

func (*RelayState) CompleteRelayByIdx

func (rs *RelayState) CompleteRelayByIdx(localIdx uint32, remoteIdx uint32) (*Relay, bool)

func (*RelayState) CopyAllRelayFor

func (rs *RelayState) CopyAllRelayFor() []*Relay

func (*RelayState) CopyRelayForIdxs

func (rs *RelayState) CopyRelayForIdxs() []uint32

func (*RelayState) CopyRelayForIps

func (rs *RelayState) CopyRelayForIps() []netip.Addr

func (*RelayState) CopyRelayIps

func (rs *RelayState) CopyRelayIps() []netip.Addr

func (*RelayState) DeleteRelay

func (rs *RelayState) DeleteRelay(ip netip.Addr)

func (*RelayState) GetRelayForByAddr

func (rs *RelayState) GetRelayForByAddr(addr netip.Addr) (*Relay, bool)

func (*RelayState) InsertRelay

func (rs *RelayState) InsertRelay(ip netip.Addr, idx uint32, r *Relay)

func (*RelayState) InsertRelayTo

func (rs *RelayState) InsertRelayTo(ip netip.Addr)

func (*RelayState) QueryRelayForByIdx

func (rs *RelayState) QueryRelayForByIdx(idx uint32) (*Relay, bool)

func (*RelayState) QueryRelayForByIp

func (rs *RelayState) QueryRelayForByIp(vpnIp netip.Addr) (*Relay, bool)

func (*RelayState) UpdateRelayForByIdxState

func (rs *RelayState) UpdateRelayForByIdxState(idx uint32, state int)

func (*RelayState) UpdateRelayForByIpState

func (rs *RelayState) UpdateRelayForByIpState(vpnIp netip.Addr, state int)

type RemoteAllowList

type RemoteAllowList struct {
	AllowList *AllowList
	// contains filtered or unexported fields
}

func NewRemoteAllowListFromConfig

func NewRemoteAllowListFromConfig(c *config.C, k, rangesKey string) (*RemoteAllowList, error)

func (*RemoteAllowList) Allow

func (al *RemoteAllowList) Allow(vpnAddr netip.Addr, udpAddr netip.Addr) bool

func (*RemoteAllowList) AllowAll

func (al *RemoteAllowList) AllowAll(vpnAddrs []netip.Addr, udpAddr netip.Addr) bool

func (*RemoteAllowList) AllowUnknownVpnAddr

func (al *RemoteAllowList) AllowUnknownVpnAddr(vpnAddr netip.Addr) bool

type RemoteList

type RemoteList struct {
	// Every interaction with internals requires a lock!
	sync.RWMutex
	// contains filtered or unexported fields
}

RemoteList is a unifying concept for lighthouse servers and clients as well as hostinfos. It serves as a local cache of query replies, host update notifications, and locally learned addresses

func NewRemoteList

func NewRemoteList(vpnAddrs []netip.Addr, shouldAdd func(netip.Addr) bool) *RemoteList

NewRemoteList creates a new empty RemoteList

func (*RemoteList) BlockRemote

func (r *RemoteList) BlockRemote(bad netip.AddrPort)

BlockRemote locks and records the address as bad, it will be excluded from the deduplicated address list

func (*RemoteList) CopyAddrs

func (r *RemoteList) CopyAddrs(preferredRanges []netip.Prefix) []netip.AddrPort

CopyAddrs locks and makes a deep copy of the deduplicated address list The deduplication work may need to occur here, so you must pass preferredRanges

func (*RemoteList) CopyBlockedRemotes

func (r *RemoteList) CopyBlockedRemotes() []netip.AddrPort

CopyBlockedRemotes locks and makes a deep copy of the blocked remotes list

func (*RemoteList) CopyCache

func (r *RemoteList) CopyCache() *CacheMap

CopyCache locks and creates a more human friendly form of the internal address cache. This may contain duplicates and blocked addresses

func (*RemoteList) ForEach

func (r *RemoteList) ForEach(preferredRanges []netip.Prefix, forEach forEachFunc)

ForEach locks and will call the forEachFunc for every deduplicated address in the list The deduplication work may need to occur here, so you must pass preferredRanges

func (*RemoteList) LearnRemote

func (r *RemoteList) LearnRemote(ownerVpnIp netip.Addr, remote netip.AddrPort)

LearnRemote locks and sets the learned slot for the owner vpn ip to the provided addr Currently this is only needed when HostInfo.SetRemote is called as that should cover both handshaking and roaming. It will mark the deduplicated address list as dirty, so do not call it unless new information is available

func (*RemoteList) Len

func (r *RemoteList) Len(preferredRanges []netip.Prefix) int

Len locks and reports the size of the deduplicated address list The deduplication work may need to occur here, so you must pass preferredRanges

func (*RemoteList) Rebuild

func (r *RemoteList) Rebuild(preferredRanges []netip.Prefix)

Rebuild locks and generates the deduplicated address list only if there is work to be done There is generally no reason to call this directly but it is safe to do so

func (*RemoteList) ResetBlockedRemotes

func (r *RemoteList) ResetBlockedRemotes()

ResetBlockedRemotes locks and clears the blocked remotes list

type TimeoutItem

type TimeoutItem[T any] struct {
	Item T
	Next *TimeoutItem[T]
}

TimeoutItem Represents an item within a tick

type TimeoutList

type TimeoutList[T any] struct {
	Head *TimeoutItem[T]
	Tail *TimeoutItem[T]
}

TimeoutList Represents a tick in the wheel

type TimerWheel

type TimerWheel[T any] struct {
	// contains filtered or unexported fields
}

func NewTimerWheel

func NewTimerWheel[T any](min, max time.Duration) *TimerWheel[T]

NewTimerWheel Builds a timer wheel and identifies the tick duration and wheel duration from the provided values Purge must be called once per entry to actually remove anything The TimerWheel does not handle concurrency on its own. Locks around access to it must be used if multiple routines are manipulating it.

func (*TimerWheel[T]) Add

func (tw *TimerWheel[T]) Add(v T, timeout time.Duration) *TimeoutItem[T]

Add will add an item to the wheel in its proper timeout. Caller should Advance the wheel prior to ensure the proper slot is used.

func (*TimerWheel[T]) Advance

func (tw *TimerWheel[T]) Advance(now time.Time)

Advance will move the wheel forward by the appropriate number of ticks for the provided time and all items passed over will be moved to the expired list. Calling Purge is necessary to remove them entirely.

func (*TimerWheel[T]) Purge

func (tw *TimerWheel[T]) Purge() (T, bool)

Purge removes and returns the first available expired item from the wheel and the 2nd argument is true. If no item is available then an empty T is returned and the 2nd argument is false.

type V4AddrPort

type V4AddrPort struct {
	Addr uint32 `protobuf:"varint,1,opt,name=Addr,proto3" json:"Addr,omitempty"`
	Port uint32 `protobuf:"varint,2,opt,name=Port,proto3" json:"Port,omitempty"`
}

func (*V4AddrPort) Descriptor

func (*V4AddrPort) Descriptor() ([]byte, []int)

func (*V4AddrPort) GetAddr

func (m *V4AddrPort) GetAddr() uint32

func (*V4AddrPort) GetPort

func (m *V4AddrPort) GetPort() uint32

func (*V4AddrPort) Marshal

func (m *V4AddrPort) Marshal() (dAtA []byte, err error)

func (*V4AddrPort) MarshalTo

func (m *V4AddrPort) MarshalTo(dAtA []byte) (int, error)

func (*V4AddrPort) MarshalToSizedBuffer

func (m *V4AddrPort) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*V4AddrPort) ProtoMessage

func (*V4AddrPort) ProtoMessage()

func (*V4AddrPort) Reset

func (m *V4AddrPort) Reset()

func (*V4AddrPort) Size

func (m *V4AddrPort) Size() (n int)

func (*V4AddrPort) String

func (m *V4AddrPort) String() string

func (*V4AddrPort) Unmarshal

func (m *V4AddrPort) Unmarshal(dAtA []byte) error

func (*V4AddrPort) XXX_DiscardUnknown

func (m *V4AddrPort) XXX_DiscardUnknown()

func (*V4AddrPort) XXX_Marshal

func (m *V4AddrPort) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*V4AddrPort) XXX_Merge

func (m *V4AddrPort) XXX_Merge(src proto.Message)

func (*V4AddrPort) XXX_Size

func (m *V4AddrPort) XXX_Size() int

func (*V4AddrPort) XXX_Unmarshal

func (m *V4AddrPort) XXX_Unmarshal(b []byte) error

type V6AddrPort

type V6AddrPort struct {
	Hi   uint64 `protobuf:"varint,1,opt,name=Hi,proto3" json:"Hi,omitempty"`
	Lo   uint64 `protobuf:"varint,2,opt,name=Lo,proto3" json:"Lo,omitempty"`
	Port uint32 `protobuf:"varint,3,opt,name=Port,proto3" json:"Port,omitempty"`
}

func (*V6AddrPort) Descriptor

func (*V6AddrPort) Descriptor() ([]byte, []int)

func (*V6AddrPort) GetHi

func (m *V6AddrPort) GetHi() uint64

func (*V6AddrPort) GetLo

func (m *V6AddrPort) GetLo() uint64

func (*V6AddrPort) GetPort

func (m *V6AddrPort) GetPort() uint32

func (*V6AddrPort) Marshal

func (m *V6AddrPort) Marshal() (dAtA []byte, err error)

func (*V6AddrPort) MarshalTo

func (m *V6AddrPort) MarshalTo(dAtA []byte) (int, error)

func (*V6AddrPort) MarshalToSizedBuffer

func (m *V6AddrPort) MarshalToSizedBuffer(dAtA []byte) (int, error)

func (*V6AddrPort) ProtoMessage

func (*V6AddrPort) ProtoMessage()

func (*V6AddrPort) Reset

func (m *V6AddrPort) Reset()

func (*V6AddrPort) Size

func (m *V6AddrPort) Size() (n int)

func (*V6AddrPort) String

func (m *V6AddrPort) String() string

func (*V6AddrPort) Unmarshal

func (m *V6AddrPort) Unmarshal(dAtA []byte) error

func (*V6AddrPort) XXX_DiscardUnknown

func (m *V6AddrPort) XXX_DiscardUnknown()

func (*V6AddrPort) XXX_Marshal

func (m *V6AddrPort) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*V6AddrPort) XXX_Merge

func (m *V6AddrPort) XXX_Merge(src proto.Message)

func (*V6AddrPort) XXX_Size

func (m *V6AddrPort) XXX_Size() int

func (*V6AddrPort) XXX_Unmarshal

func (m *V6AddrPort) XXX_Unmarshal(b []byte) error

type ViaSender

type ViaSender struct {
	// contains filtered or unexported fields
}

Directories

Path Synopsis
cmd
cmesh command
cmesh-cert command
cmesh-service command
e2e
examples
go_service command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL