Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add callback API to track allocation lifeycle #419

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

rg0now
Copy link
Contributor

@rg0now rg0now commented Nov 7, 2024

Fixes #324, #325, and #402

This PR adds a set of callbacks that can be used to track the lifecycle of TURN allocations in the server. This allows user code to be called whenever an authentication request has been processed (this can be used to mitigate DoS attacks against a server, see #402), when an allocation has been created/removed (e.g., to implement user tracking for adding quota support, see #324), when a permission has been created/removed (e.g., to log the peers a user tries to reach via the server), a channel has been created/removed (this will simplify integrating external TURN accelerators, see #360), or when an allocation ends with an error.

The implementation adds a new EventHandlers struct to the ServerConfig, defined as follows:

type EventHandlers struct {
  OnAuth func(srcAddr, dstAddr net.Addr, protocol, username, realm string, method string, verdict bool)
  OnAllocationCreated func(srcAddr, dstAddr net.Addr, protocol, username, realm string, requestedPort int)
  OnAllocationDeleted func(srcAddr, dstAddr net.Addr, protocol, username, realm string)
  OnAllocationError func(srcAddr, dstAddr net.Addr, protocol, message string)
  OnPermissionCreated func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.IP)
  OnPermissionDeleted func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.IP)
  OnChannelCreated func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.Addr, channelNumber uint16)
  OnChannelDeleted func(srcAddr, dstAddr net.Addr, protocol, username, realm string, peer net.Addr, channelNumber uint16)
}

It is OK to handle only a subset of the events.

Caveats:

  • Event handlers are called synchronously, so long-running callbacks will block the server.
  • Theoretically, allocations are allowed to change credentials during their lifetime, in that any Refresh, CreatePermission or ChannelBind message may use a different credential. Since this does not seem to be easy to implement with the PeerConnection API, credential swaps are currently no tracked.

@rg0now rg0now requested review from stv0g and Sean-Der November 7, 2024 16:42
@rg0now
Copy link
Contributor Author

rg0now commented Nov 7, 2024

CC @renandincer

Copy link

codecov bot commented Nov 7, 2024

Codecov Report

Attention: Patch coverage is 90.86294% with 18 lines in your changes missing coverage. Please review.

Project coverage is 68.62%. Comparing base (cc03474) to head (dae4d0c).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
internal/server/util.go 73.07% 5 Missing and 2 partials ⚠️
internal/allocation/five_tuple.go 60.00% 4 Missing ⚠️
server.go 33.33% 3 Missing and 1 partial ⚠️
internal/server/nonce.go 50.00% 0 Missing and 1 partial ⚠️
relay_address_generator_range.go 0.00% 1 Missing ⚠️
server_config.go 97.43% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #419      +/-   ##
==========================================
+ Coverage   68.15%   68.62%   +0.47%     
==========================================
  Files          43       43              
  Lines        2352     3095     +743     
==========================================
+ Hits         1603     2124     +521     
- Misses        582      804     +222     
  Partials      167      167              
Flag Coverage Δ
go 68.62% <90.86%> (+0.47%) ⬆️
wasm 25.62% <3.04%> (-2.27%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@renandincer
Copy link

I just looked at it briefly @rg0now! Thank you for PRing this in.

I think it might be useful to get a handle to the PacketConn from OnAllocatedCreated as well. This might be useful for rate limiting. What do you think?

@rg0now
Copy link
Contributor Author

rg0now commented Nov 12, 2024

I think a better way to handle rate limiting would be to provide a RelayAddressGenerator.AllocatePacketConn to the server that will emit rate-limited packetconns. This works even today. The only issue with that approach is if we need user context for applying rate limiting (i.e., when different users may get different rate limits), since currently we miss the user context in the RelayAddressGenerator interface handlers. But then again, it would somehow be more adequate to add the user context there. Wdyt?

@renandincer
Copy link

Agreed. Only issue is that would be a breaking API change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Add AllocationHandler
2 participants