mirror of
https://github.com/pion/ice.git
synced 2025-09-26 19:41:11 +08:00
Add more configuration to AgentOptions
This commit is contained in:
@@ -67,3 +67,88 @@ func WithNominationAttribute(attrType uint16) AgentOption {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithIncludeLoopback includes loopback addresses in the candidate list.
|
||||
// By default, loopback addresses are excluded.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// agent, err := NewAgentWithOptions(WithIncludeLoopback())
|
||||
func WithIncludeLoopback() AgentOption {
|
||||
return func(a *Agent) error {
|
||||
a.includeLoopback = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithTCPPriorityOffset sets a number which is subtracted from the default (UDP) candidate type preference
|
||||
// for host, srflx and prfx candidate types. It helps to configure relative preference of UDP candidates
|
||||
// against TCP ones. Relay candidates for TCP and UDP are always 0 and not affected by this setting.
|
||||
// When not set, defaultTCPPriorityOffset (27) is used.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// agent, err := NewAgentWithOptions(WithTCPPriorityOffset(50))
|
||||
func WithTCPPriorityOffset(offset uint16) AgentOption {
|
||||
return func(a *Agent) error {
|
||||
a.tcpPriorityOffset = offset
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithDisableActiveTCP disables Active TCP candidates.
|
||||
// When TCP is enabled, Active TCP candidates will be created when a new passive TCP remote candidate is added
|
||||
// unless this option is used.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// agent, err := NewAgentWithOptions(WithDisableActiveTCP())
|
||||
func WithDisableActiveTCP() AgentOption {
|
||||
return func(a *Agent) error {
|
||||
a.disableActiveTCP = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithBindingRequestHandler sets a handler to allow applications to perform logic on incoming STUN Binding Requests.
|
||||
// This was implemented to allow users to:
|
||||
// - Log incoming Binding Requests for debugging
|
||||
// - Implement draft-thatcher-ice-renomination
|
||||
// - Implement custom CandidatePair switching logic
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// handler := func(m *stun.Message, local, remote Candidate, pair *CandidatePair) bool {
|
||||
// log.Printf("Binding request from %s to %s", remote.Address(), local.Address())
|
||||
// return true // Accept the request
|
||||
// }
|
||||
// agent, err := NewAgentWithOptions(WithBindingRequestHandler(handler))
|
||||
func WithBindingRequestHandler(
|
||||
handler func(m *stun.Message, local, remote Candidate, pair *CandidatePair) bool,
|
||||
) AgentOption {
|
||||
return func(a *Agent) error {
|
||||
a.userBindingRequestHandler = handler
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithEnableUseCandidateCheckPriority enables checking for equal or higher priority when
|
||||
// switching selected candidate pair if the peer requests USE-CANDIDATE and agent is a lite agent.
|
||||
// This is disabled by default, i.e. when peer requests USE-CANDIDATE, the selected pair will be
|
||||
// switched to that irrespective of relative priority between current selected pair
|
||||
// and priority of the pair being switched to.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// agent, err := NewAgentWithOptions(WithEnableUseCandidateCheckPriority())
|
||||
func WithEnableUseCandidateCheckPriority() AgentOption {
|
||||
return func(a *Agent) error {
|
||||
a.enableUseCandidateCheckPriority = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,46 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// testBooleanOption is a helper function to test boolean agent options.
|
||||
type booleanOptionTest struct {
|
||||
optionFunc func() AgentOption
|
||||
getValue func(*Agent) bool
|
||||
configSetter func(*AgentConfig, bool)
|
||||
}
|
||||
|
||||
func testBooleanOption(t *testing.T, test booleanOptionTest, optionName string) {
|
||||
t.Helper()
|
||||
|
||||
t.Run("enables "+optionName, func(t *testing.T) {
|
||||
agent, err := NewAgentWithOptions(test.optionFunc())
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.True(t, test.getValue(agent))
|
||||
})
|
||||
|
||||
t.Run("default is false", func(t *testing.T) {
|
||||
agent, err := NewAgentWithOptions()
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.False(t, test.getValue(agent))
|
||||
})
|
||||
|
||||
t.Run("works with config", func(t *testing.T) {
|
||||
config := &AgentConfig{
|
||||
NetworkTypes: []NetworkType{NetworkTypeUDP4},
|
||||
}
|
||||
test.configSetter(config, true)
|
||||
|
||||
agent, err := NewAgent(config)
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.True(t, test.getValue(agent))
|
||||
})
|
||||
}
|
||||
|
||||
func TestDefaultNominationValueGenerator(t *testing.T) {
|
||||
t.Run("generates incrementing values", func(t *testing.T) {
|
||||
generator := DefaultNominationValueGenerator()
|
||||
@@ -108,3 +148,151 @@ func TestWithNominationAttribute(t *testing.T) {
|
||||
assert.Equal(t, stun.AttrType(0x0030), agent.nominationAttribute)
|
||||
})
|
||||
}
|
||||
|
||||
func TestWithIncludeLoopback(t *testing.T) {
|
||||
testBooleanOption(t, booleanOptionTest{
|
||||
optionFunc: WithIncludeLoopback,
|
||||
getValue: func(a *Agent) bool { return a.includeLoopback },
|
||||
configSetter: func(c *AgentConfig, v bool) { c.IncludeLoopback = v },
|
||||
}, "loopback addresses")
|
||||
}
|
||||
|
||||
func TestWithTCPPriorityOffset(t *testing.T) {
|
||||
t.Run("sets custom TCP priority offset", func(t *testing.T) {
|
||||
customOffset := uint16(50)
|
||||
agent, err := NewAgentWithOptions(WithTCPPriorityOffset(customOffset))
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.Equal(t, customOffset, agent.tcpPriorityOffset)
|
||||
})
|
||||
|
||||
t.Run("default is 27", func(t *testing.T) {
|
||||
agent, err := NewAgentWithOptions()
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
// The default is set via initWithDefaults
|
||||
assert.Equal(t, uint16(27), agent.tcpPriorityOffset)
|
||||
})
|
||||
|
||||
t.Run("works with config", func(t *testing.T) {
|
||||
customOffset := uint16(100)
|
||||
config := &AgentConfig{
|
||||
NetworkTypes: []NetworkType{NetworkTypeUDP4},
|
||||
TCPPriorityOffset: &customOffset,
|
||||
}
|
||||
|
||||
agent, err := NewAgent(config)
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.Equal(t, customOffset, agent.tcpPriorityOffset)
|
||||
})
|
||||
}
|
||||
|
||||
func TestWithDisableActiveTCP(t *testing.T) {
|
||||
testBooleanOption(t, booleanOptionTest{
|
||||
optionFunc: WithDisableActiveTCP,
|
||||
getValue: func(a *Agent) bool { return a.disableActiveTCP },
|
||||
configSetter: func(c *AgentConfig, v bool) { c.DisableActiveTCP = v },
|
||||
}, "active TCP disabling")
|
||||
}
|
||||
|
||||
func TestWithBindingRequestHandler(t *testing.T) {
|
||||
t.Run("sets binding request handler", func(t *testing.T) {
|
||||
handlerCalled := false
|
||||
handler := func(m *stun.Message, local, remote Candidate, pair *CandidatePair) bool {
|
||||
handlerCalled = true
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
agent, err := NewAgentWithOptions(WithBindingRequestHandler(handler))
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.NotNil(t, agent.userBindingRequestHandler)
|
||||
|
||||
// Test that the handler is actually the one we set
|
||||
// We can't directly compare functions, but we can call it
|
||||
if agent.userBindingRequestHandler != nil {
|
||||
agent.userBindingRequestHandler(nil, nil, nil, nil)
|
||||
assert.True(t, handlerCalled)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("default is nil", func(t *testing.T) {
|
||||
agent, err := NewAgentWithOptions()
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.Nil(t, agent.userBindingRequestHandler)
|
||||
})
|
||||
|
||||
t.Run("works with config", func(t *testing.T) {
|
||||
handlerCalled := false
|
||||
handler := func(m *stun.Message, local, remote Candidate, pair *CandidatePair) bool {
|
||||
handlerCalled = true
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
config := &AgentConfig{
|
||||
NetworkTypes: []NetworkType{NetworkTypeUDP4},
|
||||
BindingRequestHandler: handler,
|
||||
}
|
||||
|
||||
agent, err := NewAgent(config)
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.NotNil(t, agent.userBindingRequestHandler)
|
||||
|
||||
if agent.userBindingRequestHandler != nil {
|
||||
agent.userBindingRequestHandler(nil, nil, nil, nil)
|
||||
assert.True(t, handlerCalled)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestWithEnableUseCandidateCheckPriority(t *testing.T) {
|
||||
testBooleanOption(t, booleanOptionTest{
|
||||
optionFunc: WithEnableUseCandidateCheckPriority,
|
||||
getValue: func(a *Agent) bool { return a.enableUseCandidateCheckPriority },
|
||||
configSetter: func(c *AgentConfig, v bool) { c.EnableUseCandidateCheckPriority = v },
|
||||
}, "use candidate check priority")
|
||||
}
|
||||
|
||||
func TestMultipleConfigOptions(t *testing.T) {
|
||||
t.Run("can apply multiple options", func(t *testing.T) {
|
||||
customOffset := uint16(100)
|
||||
handlerCalled := false
|
||||
handler := func(m *stun.Message, local, remote Candidate, pair *CandidatePair) bool {
|
||||
handlerCalled = true
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
agent, err := NewAgentWithOptions(
|
||||
WithIncludeLoopback(),
|
||||
WithTCPPriorityOffset(customOffset),
|
||||
WithDisableActiveTCP(),
|
||||
WithBindingRequestHandler(handler),
|
||||
WithEnableUseCandidateCheckPriority(),
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
defer agent.Close() //nolint:errcheck
|
||||
|
||||
assert.True(t, agent.includeLoopback)
|
||||
assert.Equal(t, customOffset, agent.tcpPriorityOffset)
|
||||
assert.True(t, agent.disableActiveTCP)
|
||||
assert.NotNil(t, agent.userBindingRequestHandler)
|
||||
assert.True(t, agent.enableUseCandidateCheckPriority)
|
||||
|
||||
if agent.userBindingRequestHandler != nil {
|
||||
agent.userBindingRequestHandler(nil, nil, nil, nil)
|
||||
assert.True(t, handlerCalled)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user