From 2d60776193ba51723af01dbcbd9c8ce2102aea6b Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Sun, 8 Dec 2019 19:48:42 -0800 Subject: [PATCH] Add MulticastDNSHostName to AgentConfig Allow users to pass in a static MulticastDNSHostName, this can be used to connect peers in a LAN without signaling. If you set a static uFrag/uPwd on either side and have a static hostname you can gather without knowing an IP Address on either side. --- agent.go | 16 +++++++++++++--- errors.go | 3 +++ go.sum | 1 + mdns_test.go | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/agent.go b/agent.go index 2e55380..4cfe3f4 100644 --- a/agent.go +++ b/agent.go @@ -199,6 +199,9 @@ type AgentConfig struct { // MulticastDNSMode controls mDNS behavior for the ICE agent MulticastDNSMode MulticastDNSMode + // MulticastDNSHostName controls the hostname for this agent. If none is specified a random one will be generated + MulticastDNSHostName string + // ConnectionTimeout defaults to 30 seconds when this property is nil. // If the duration is 0, we will never timeout this connection. ConnectionTimeout *time.Duration @@ -313,6 +316,7 @@ func createMulticastDNS(mDNSMode MulticastDNSMode, mDNSName string, log logging. // NewAgent creates a new Agent func NewAgent(config *AgentConfig) (*Agent, error) { + var err error if config.PortMax < config.PortMin { return nil, ErrPort } @@ -337,9 +341,15 @@ func NewAgent(config *AgentConfig) (*Agent, error) { localPwd = config.LocalPwd } - mDNSName, err := generateMulticastDNSName() - if err != nil { - return nil, err + mDNSName := config.MulticastDNSHostName + if mDNSName == "" { + if mDNSName, err = generateMulticastDNSName(); err != nil { + return nil, err + } + } + + if !strings.HasSuffix(mDNSName, ".local") || len(strings.Split(mDNSName, ".")) != 2 { + return nil, ErrInvalidMulticastDNSHostName } mDNSMode := config.MulticastDNSMode diff --git a/errors.go b/errors.go index edc34b8..79e484c 100644 --- a/errors.go +++ b/errors.go @@ -94,4 +94,7 @@ var ( // ErrIneffectiveNAT1To1IPMappingSrflx indicates that 1:1 NAT IP mapping for srflx candidate is // requested, but the srflx candidate type is disabled. ErrIneffectiveNAT1To1IPMappingSrflx = errors.New("1:1 NAT IP mapping for srflx candidate ineffective") + + // ErrInvalidMulticastDNSHostName indicates an invalid MulticastDNSHostName + ErrInvalidMulticastDNSHostName = errors.New("invalid mDNS HostName, must end with .local and can only contain a single '.'") ) diff --git a/go.sum b/go.sum index e968289..7d7f4f4 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b h1:lkjdUzSyJ5P1+eal9fxXX9Xg2BTfswsonKUse48C0uE= golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5PW3vNmnN64U2ZW759Lk= golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/mdns_test.go b/mdns_test.go index 541b53c..b49acf5 100644 --- a/mdns_test.go +++ b/mdns_test.go @@ -1,6 +1,7 @@ package ice import ( + "context" "testing" "time" @@ -93,3 +94,39 @@ func TestMulticastDNSMixedConnection(t *testing.T) { assert.NoError(t, aAgent.Close()) assert.NoError(t, bAgent.Close()) } + +func TestMulticastDNSStaticHostName(t *testing.T) { + lim := test.TimeOut(time.Second * 30) + defer lim.Stop() + + report := test.CheckRoutines(t) + defer report() + + _, err := NewAgent(&AgentConfig{ + NetworkTypes: []NetworkType{NetworkTypeUDP4}, + CandidateTypes: []CandidateType{CandidateTypeHost}, + MulticastDNSMode: MulticastDNSModeQueryAndGather, + MulticastDNSHostName: "invalidHostName", + }) + assert.Equal(t, err, ErrInvalidMulticastDNSHostName) + + agent, err := NewAgent(&AgentConfig{ + Trickle: true, + NetworkTypes: []NetworkType{NetworkTypeUDP4}, + CandidateTypes: []CandidateType{CandidateTypeHost}, + MulticastDNSMode: MulticastDNSModeQueryAndGather, + MulticastDNSHostName: "validName.local", + }) + assert.NoError(t, err) + + correctHostName, resolveFunc := context.WithCancel(context.Background()) + assert.NoError(t, agent.OnCandidate(func(c Candidate) { + if c.Address() == "validName.local" { + resolveFunc() + } + })) + + assert.NoError(t, agent.GatherCandidates()) + <-correctHostName.Done() + assert.NoError(t, agent.Close()) +}