diff --git a/internal/allocation/allocation.go b/internal/allocation/allocation.go index 687ff9f0..9d0286dc 100644 --- a/internal/allocation/allocation.go +++ b/internal/allocation/allocation.go @@ -167,6 +167,7 @@ func (a *Allocation) AddChannelBind(c *ChannelBind, lifetime time.Duration) erro Protocol: a.fiveTuple.Protocol, Username: a.username, Realm: a.realm, + RelayAddr: a.RelayAddr, PeerAddr: c.Peer, ChannelNumber: uint16(c.Number), }) @@ -197,6 +198,7 @@ func (a *Allocation) RemoveChannelBind(number proto.ChannelNumber) bool { Protocol: a.fiveTuple.Protocol, Username: a.username, Realm: a.realm, + RelayAddr: a.RelayAddr, PeerAddr: a.channelBindings[i].Peer, ChannelNumber: uint16(a.channelBindings[i].Number), }) diff --git a/internal/allocation/allocation_manager.go b/internal/allocation/allocation_manager.go index eaa7aefd..6567e8a1 100644 --- a/internal/allocation/allocation_manager.go +++ b/internal/allocation/allocation_manager.go @@ -137,6 +137,7 @@ func (m *Manager) CreateAllocation(fiveTuple *FiveTuple, turnSocket net.PacketCo Protocol: UDP, Username: username, Realm: realm, + RelayAddr: relayAddr, RequestedPort: requestedPort, }) } diff --git a/internal/allocation/event_handler.go b/internal/allocation/event_handler.go index 192414e6..b5b718c2 100644 --- a/internal/allocation/event_handler.go +++ b/internal/allocation/event_handler.go @@ -25,14 +25,14 @@ const ( // EventHandlerArgs is a set of arguments passed from the low-level event callbacks to the server. type EventHandlerArgs struct { - Type EventHandlerType - SrcAddr, DstAddr, PeerAddr net.Addr - Protocol Protocol - Username, Realm, Method, Message string - Verdict bool - RequestedPort int - PeerIP net.IP - ChannelNumber uint16 + Type EventHandlerType + SrcAddr, DstAddr, RelayAddr, PeerAddr net.Addr + Protocol Protocol + Username, Realm, Method, Message string + Verdict bool + RequestedPort int + PeerIP net.IP + ChannelNumber uint16 } // EventHandler is a callback used by the server to surface allocation lifecycle events. diff --git a/server_config.go b/server_config.go index bee560f9..4dd55c6c 100644 --- a/server_config.go +++ b/server_config.go @@ -114,9 +114,10 @@ type EventHandlers struct { // triggering the authentication request (either "Allocate", "Refresh" "CreatePermission", // or "ChannelBind"), and the verdict is the authentication result. OnAuth func(srcAddr, dstAddr net.Addr, protocol, username, realm string, method string, verdict bool) - // OnAllocationCreated is called after a new allocation has been made. The relay port - // requested by the client (if any) is passed in requestedPort. - OnAllocationCreated func(srcAddr, dstAddr net.Addr, protocol, username, realm string, requestedPort int) + // OnAllocationCreated is called after a new allocation has been made. The relayAddr + // argument specifies the relay address and requestedPort is the port requested by the + // client (if any). + OnAllocationCreated func(srcAddr, dstAddr net.Addr, protocol, username, realm string, relayAddr net.Addr, requestedPort int) // OnAllocationDeleted is called after an allocation has been removed. OnAllocationDeleted func(srcAddr, dstAddr net.Addr, protocol, username, realm string) // OnAllocationError is called when the readloop hdndling an allocation exits with an @@ -127,12 +128,14 @@ type EventHandlers struct { // OnPermissionDeleted is called after a permission for a given IP address has been // removed. OnPermissionDeleted func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.IP) - // OnChannelCreated is called after a new channel has been made with a given channel - // number. - OnChannelCreated func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.Addr, channelNumber uint16) - // OnChannelDeleted is called after a channel with the given channel number has been - // removed from the server. - OnChannelDeleted func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.Addr, channelNumber uint16) + // OnChannelCreated is called after a new channel has been made. The relay address, the + // peer address and the channel number can be used to uniquely identify the channel + // created. + OnChannelCreated func(srcAddr, dstAddr net.Addr, protocol, username, realm string, relayAddr, peer net.Addr, channelNumber uint16) + // OnChannelDeleted is called after a channel has been removed from the server. The relay + // address, the peer address and the channel number can be used to uniquely identify the + // channel deleted. + OnChannelDeleted func(srcAddr, dstAddr net.Addr, protocol, username, realm string, relayAddr, peer net.Addr, channelNumber uint16) } func genericEventHandler(handlers EventHandlers) allocation.EventHandler { @@ -146,7 +149,7 @@ func genericEventHandler(handlers EventHandlers) allocation.EventHandler { case allocation.OnAllocationCreated: if handlers.OnAllocationCreated != nil { handlers.OnAllocationCreated(arg.SrcAddr, arg.DstAddr, arg.Protocol.String(), - arg.Username, arg.Realm, arg.RequestedPort) + arg.Username, arg.Realm, arg.RelayAddr, arg.RequestedPort) } case allocation.OnAllocationDeleted: if handlers.OnAllocationDeleted != nil { @@ -166,12 +169,12 @@ func genericEventHandler(handlers EventHandlers) allocation.EventHandler { case allocation.OnChannelCreated: if handlers.OnChannelCreated != nil { handlers.OnChannelCreated(arg.SrcAddr, arg.DstAddr, arg.Protocol.String(), - arg.Username, arg.Realm, arg.PeerAddr, arg.ChannelNumber) + arg.Username, arg.Realm, arg.RelayAddr, arg.PeerAddr, arg.ChannelNumber) } case allocation.OnChannelDeleted: if handlers.OnChannelDeleted != nil { handlers.OnChannelDeleted(arg.SrcAddr, arg.DstAddr, arg.Protocol.String(), - arg.Username, arg.Realm, arg.PeerAddr, arg.ChannelNumber) + arg.Username, arg.Realm, arg.RelayAddr, arg.PeerAddr, arg.ChannelNumber) } default: } diff --git a/server_test.go b/server_test.go index 19756df2..ab53f69b 100644 --- a/server_test.go +++ b/server_test.go @@ -635,11 +635,14 @@ func TestServerVNet(t *testing.T) { assert.Equal(t, "pion.ly", event.Realm) assert.Equal(t, 0, event.RequestedPort) - relayAddr := relayConn.LocalAddr() - log.Debugf("relay-address: %s", relayAddr.String()) - udpAddr, ok = relayAddr.(*net.UDPAddr) + relayNetAddr := relayConn.LocalAddr() + log.Debugf("relay-address: %s", relayNetAddr.String()) + relayAddr, ok := relayNetAddr.(*net.UDPAddr) assert.True(t, ok) - + udpAddr, ok = event.RelayAddr.(*net.UDPAddr) + assert.True(t, ok) + assert.True(t, relayAddr.IP.Equal(udpAddr.IP)) + assert.Equal(t, relayAddr.Port, udpAddr.Port) // The transport relay address should have IP address that was assigned to the server. assert.True(t, udpAddr.IP.Equal(net.IPv4(1, 2, 3, 4)), "should match") @@ -708,6 +711,10 @@ func TestServerVNet(t *testing.T) { assert.Equal(t, allocation.UDP, event.Protocol) assert.Equal(t, "user", event.Username) assert.Equal(t, "pion.ly", event.Realm) + udpAddr, ok = event.RelayAddr.(*net.UDPAddr) + assert.True(t, ok) + assert.True(t, relayAddr.IP.Equal(udpAddr.IP)) + assert.Equal(t, relayAddr.Port, udpAddr.Port) // obtain the channel id a := v.server.allocationManagers[0].GetAllocation(&allocation.FiveTuple{ @@ -764,6 +771,10 @@ func TestServerVNet(t *testing.T) { assert.Equal(t, allocation.UDP, event.Protocol) assert.Equal(t, "user", event.Username) assert.Equal(t, "pion.ly", event.Realm) + udpAddr, ok = event.RelayAddr.(*net.UDPAddr) + assert.True(t, ok) + assert.True(t, relayAddr.IP.Equal(udpAddr.IP)) + assert.Equal(t, relayAddr.Port, udpAddr.Port) assert.Equal(t, channelBind.Number, proto.ChannelNumber(event.ChannelNumber)) event, ok = expectEvent(events) @@ -876,13 +887,17 @@ func TestServerVNet(t *testing.T) { t.Run("AllocationEventHandlers", func(t *testing.T) { peerAddr := &net.UDPAddr{IP: net.ParseIP("1.2.3.5"), Port: 80} + relayAddrIP := net.ParseIP("1.2.3.4") allocCreated, allocDeleted := &atomic.Int32{}, &atomic.Int32{} permissionCreated, permissionDeleted := &atomic.Int32{}, &atomic.Int32{} channelCreated, channelDeleted := &atomic.Int32{}, &atomic.Int32{} allocCallback := &EventHandlers{ - OnAllocationCreated: func(srcAddr, dstAddr net.Addr, protocol, username, realm string, requestedPort int) { + OnAllocationCreated: func(srcAddr, dstAddr net.Addr, protocol, username, realm string, relayAddr net.Addr, requestedPort int) { checkAllocation(srcAddr, dstAddr, protocol, username, realm) assert.Equal(t, 0, requestedPort) + udpAddr, ok := relayAddr.(*net.UDPAddr) + assert.True(t, ok) + assert.True(t, relayAddrIP.Equal(udpAddr.IP)) allocCreated.Add(1) }, OnAllocationDeleted: func(srcAddr, dstAddr net.Addr, protocol, username, realm string) { @@ -899,21 +914,27 @@ func TestServerVNet(t *testing.T) { assert.True(t, net.ParseIP("1.2.3.5").Equal(peer)) permissionDeleted.Add(1) }, - OnChannelCreated: func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.Addr, channelNumber uint16) { + OnChannelCreated: func(srcAddr, dstAddr net.Addr, protocol, username, realm string, relayAddr, peer net.Addr, channelNumber uint16) { checkAllocation(srcAddr, dstAddr, protocol, username, realm) addr, ok := peer.(*net.UDPAddr) assert.True(t, ok) assert.True(t, addr.IP.Equal(peerAddr.IP)) assert.Equal(t, peerAddr.Port, addr.Port) + udpAddr, ok := relayAddr.(*net.UDPAddr) + assert.True(t, ok) + assert.True(t, relayAddrIP.Equal(udpAddr.IP)) assert.NotZero(t, channelNumber) channelCreated.Add(1) }, - OnChannelDeleted: func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.Addr, channelNumber uint16) { + OnChannelDeleted: func(srcAddr, dstAddr net.Addr, protocol, username, realm string, relayAddr, peer net.Addr, channelNumber uint16) { checkAllocation(srcAddr, dstAddr, protocol, username, realm) addr, ok := peer.(*net.UDPAddr) assert.True(t, ok) assert.True(t, addr.IP.Equal(peerAddr.IP)) assert.Equal(t, peerAddr.Port, addr.Port) + udpAddr, ok := relayAddr.(*net.UDPAddr) + assert.True(t, ok) + assert.True(t, relayAddrIP.Equal(udpAddr.IP)) assert.NotZero(t, channelNumber) channelDeleted.Add(1) },