The Stun Controller is used by Stun Clients and Peers to communicate with a Stun Server More...
Inherits IDisposable.
Public Member Functions | |
delegate void | DataHandler (AttributeData data, IPEndPoint source, bool fromRelay) |
Defines the format for a DataHandler method. More... | |
Controller (ControllerConfig config, Socket s=null, Action< string > onFatalError=null) | |
Construct a Stun Controller to communicate with a Stun Server at the specificed address and port, optionally using the specified credentials. More... | |
void | AddRemoteCredentials (Credentials c, IPEndPoint endPoint, IPEndPoint from, IPEndPoint allocation=null) |
Credentials | GetRemoteCredentials (IPEndPoint endPoint, IPEndPoint from, IPEndPoint allocation=null) |
void | AddLocalCredentials (Credentials c) |
bool | SendMessage (Message message, IPEndPoint target, IPEndPoint source) |
void | SocketSend (byte[] data, int offset, int count, IPEndPoint destination) |
void | ReceiveBytes (byte[] buffer, int index, int count, IPEndPoint source, IPEndPoint receivedAt, bool fromRelay) |
void | HandleResponse (Transaction< Message > transaction, Message response, IPEndPoint source, IPEndPoint receivedAt) |
Message | ReadMessage (byte[] buffer, ref int bufferIndex, int bufferLength) |
Transform some bytes into a Stun Message More... | |
void | RevokeAllBindings () |
void | RevokeBinding (IPEndPoint target, IPEndPoint source) |
Transaction< Message > | AddTransaction (Message message, Action< Transaction< Message >> onComplete, Action< Transaction< Message >> onFail, IPEndPoint target, IPEndPoint source, IPEndPoint associatedAllocation=null, int overrideRetransmissionCount=-1, int overrideTimeout=1) |
Add a transaction for an outgoing Request. More... | |
T | GetExtension< T > () |
void | AddExtension (IStunExtension extension) |
void | SendBindRequest (Action< Transaction< Message >> onBindComplete, Action< Transaction< Message >> onBindError) |
void | SendBindRequest (Action< Transaction< Message >> onBindComplete, Action< Transaction< Message >> onBindError, List< Attribute > attributes, IPEndPoint target, IPEndPoint source, int overrideMaxResend=-1) |
Send a Bind Request to the Stun server. Call onBindComplete when the Response is received. More... | |
Message | ConstructBindRequest (List< Attribute > attributes, IPEndPoint target, IPEndPoint source) |
void | OnBindComplete (Transaction< Message > transaction, Action< Transaction< Message >> callback=null, Action< Transaction< Message >> errorCallback=null) |
void | SendBindIndication (IPEndPoint target, IPEndPoint source) |
void | QueueRebind (IPEndPoint target, IPEndPoint source) |
void | ReSend (Transaction< Message > transaction) |
Re-send a request from a failed transaction More... | |
Transaction< Message > | SendRequest (Message message, IPEndPoint target, IPEndPoint source, IPEndPoint associatedAllocation=null, Action< Transaction< Message >> onResponse=null, Action< Transaction< Message >> onFail=null, int overrideMaxResend=-1, int overrideTimeout=-1) |
Transaction< Message > | Send (Message message, IPEndPoint target, IPEndPoint source, IPEndPoint associatedAllocation=null, Action< Transaction< Message >> onResponse=null, Action< Transaction< Message >> onFail=null, int overrideMaxResend=-1, int overrideTimeout=-1) |
Send a message to the Stun server. Optionally call onResponse when a response is received. More... | |
void | HandleIndication (Message message, IPEndPoint source, IPEndPoint receivedAt) |
Handle an INDICATION Message from the Stun server. More... | |
void | HandleSuccessResponse (Transaction< Message > transaction, Message response, IPEndPoint source, IPEndPoint receivedAt) |
Handle a SUCCESS_RESPONSE Message from the Stun server More... | |
void | HandleRequest (Message request, byte[] buffer, IPEndPoint source, IPEndPoint receivedAt) |
Handle a SUCCESS_RESPONSE Message from the Stun server More... | |
bool | ValidateMessage (Message request, byte[] buffer) |
void | HandleBindRequest (Message request, IPEndPoint source, IPEndPoint receivedAt) |
void | SendBindSuccessResponse (IPEndPoint target, IPEndPoint receivedAt, Message request) |
void | SendBindErrorResponse (IPEndPoint target, IPEndPoint receivedAt, Message request) |
Message | ConstructErrorResponse (MessageMethod method, ushort errorCode, string errorMessage, ReadOnlyByteArray transactionID) |
void | SendErrorResponse (MessageMethod method, ushort errorCode, string errorMessage, IPEndPoint target, IPEndPoint receivedAt, Message request) |
void | HandleErrorResponse (Transaction< Message > transaction, Message response, IPEndPoint source, IPEndPoint receivedAt) |
Handle an ERROR_RESPONSE Message from the Stun server More... | |
bool | HandleErrorAlternateServer (Transaction< Message > transaction, Message response, IPEndPoint source) |
bool | HandleErrorUnauthorizedRequest (Transaction< Message > transaction, Message response, IPEndPoint source) |
Handle unauthorised request error More... | |
void | Dispose () |
Dispose of the Controller and all extensions and timers, and close the socket More... | |
Public Attributes | |
readonly TransactionList< Message > | openTransactions = new TransactionList<Message>() |
BufferPool | bufferPool |
byte[] | receiveBuffer = new byte[4096] |
Dictionary< IPSet, Credentials > | credentialsForEndPoint = new Dictionary<IPSet, Credentials>() |
The set of credentials to send with Requests that requires authentication. More... | |
Dictionary< string, Credentials > | localCredentials = new Dictionary<string, Credentials>() |
The credentials to use when authenticating requests made to this client. More... | |
readonly ControllerConfig | config |
object | bandwidthLock = new object() |
int | bandwidthUsedThisSecond = 0 |
Timer | bandwidthTimer |
readonly IPEndPoint | localEndPoint |
DataHandler | multiplexedDataHandler |
The DataHandler to use for handling multiplxed data More... | |
Static Public Attributes | |
const int | BINDING_EXPIRATION_TIME = 2 * 60 * 1000 |
How often to refresh bindings More... | |
const uint | COOKIE = 0x2112A442 |
This magic constant is included in every Stun message to identify it as a Stun message. More... | |
static readonly uint | COOKIE_N |
This is the same thing as the COOKIE but stored in network byte order. More... | |
static ReadOnlyByteArray | COOKIE_BYTES |
static ReadOnlyByteArray | COOKIE_BYTES_N |
The Stun Controller is used by Stun Clients and Peers to communicate with a Stun Server
The Stun Controller uses a Socket to communicate with a Stun Server over UDP. The behaviour of the controller and the format of the messages are specified in RFC 5389 and RFC 5780. The main purpose of the controller is to use a Bind Request to get this Peer's server reflexive address. It can also be used to perform NAT Behaviour Discovery.
The controller handles authentication, but authentication is not needed for Bind Requests so it is ok to leave the username and password blank if that's all you need to do.
NobleConnect.Stun.Controller.Controller | ( | ControllerConfig | config, |
Socket | s = null , |
||
Action< string > | onFatalError = null |
||
) |
Construct a Stun Controller to communicate with a Stun Server at the specificed address and port, optionally using the specified credentials.
This creates the Socket and starts listening for Messages from the Stun server.
void NobleConnect.Stun.Controller.AddExtension | ( | IStunExtension | extension | ) |
void NobleConnect.Stun.Controller.AddLocalCredentials | ( | Credentials | c | ) |
void NobleConnect.Stun.Controller.AddRemoteCredentials | ( | Credentials | c, |
IPEndPoint | endPoint, | ||
IPEndPoint | from, | ||
IPEndPoint | allocation = null |
||
) |
Transaction<Message> NobleConnect.Stun.Controller.AddTransaction | ( | Message | message, |
Action< Transaction< Message >> | onComplete, | ||
Action< Transaction< Message >> | onFail, | ||
IPEndPoint | target, | ||
IPEndPoint | source, | ||
IPEndPoint | associatedAllocation = null , |
||
int | overrideRetransmissionCount = -1 , |
||
int | overrideTimeout = 1 |
||
) |
Add a transaction for an outgoing Request.
Transactions are used to keep track of which Request and Respone belongs to. They also store the callback so we can pass the Response on to the application to do something useful with.
message | |
onComplete |
Message NobleConnect.Stun.Controller.ConstructBindRequest | ( | List< Attribute > | attributes, |
IPEndPoint | target, | ||
IPEndPoint | source | ||
) |
Message NobleConnect.Stun.Controller.ConstructErrorResponse | ( | MessageMethod | method, |
ushort | errorCode, | ||
string | errorMessage, | ||
ReadOnlyByteArray | transactionID | ||
) |
delegate void NobleConnect.Stun.Controller.DataHandler | ( | AttributeData | data, |
IPEndPoint | source, | ||
bool | fromRelay | ||
) |
Defines the format for a DataHandler method.
This format is used for both the multiplexedDataHandler and for handling Data messages in Turn.
data | |
source |
void NobleConnect.Stun.Controller.Dispose | ( | ) |
Dispose of the Controller and all extensions and timers, and close the socket
T NobleConnect.Stun.Controller.GetExtension< T > | ( | ) |
T | : | IStunExtension |
Credentials NobleConnect.Stun.Controller.GetRemoteCredentials | ( | IPEndPoint | endPoint, |
IPEndPoint | from, | ||
IPEndPoint | allocation = null |
||
) |
void NobleConnect.Stun.Controller.HandleBindRequest | ( | Message | request, |
IPEndPoint | source, | ||
IPEndPoint | receivedAt | ||
) |
bool NobleConnect.Stun.Controller.HandleErrorAlternateServer | ( | Transaction< Message > | transaction, |
Message | response, | ||
IPEndPoint | source | ||
) |
void NobleConnect.Stun.Controller.HandleErrorResponse | ( | Transaction< Message > | transaction, |
Message | response, | ||
IPEndPoint | source, | ||
IPEndPoint | receivedAt | ||
) |
bool NobleConnect.Stun.Controller.HandleErrorUnauthorizedRequest | ( | Transaction< Message > | transaction, |
Message | response, | ||
IPEndPoint | source | ||
) |
Handle unauthorised request error
<rmarks> This error is part of the normal authentication flow which goes something like: Send a request without credentials Get this error as a response, which includes the realm and the nonce Use the realm and the nonce to create credentials and message integrity attribute Resend the original request with credentials </rmarks>
transaction | |
response |
void NobleConnect.Stun.Controller.HandleIndication | ( | Message | message, |
IPEndPoint | source, | ||
IPEndPoint | receivedAt | ||
) |
Handle an INDICATION Message from the Stun server.
This does nothing in the Stun Controller but may do things in extensions
message | |
transaction |
void NobleConnect.Stun.Controller.HandleRequest | ( | Message | request, |
byte[] | buffer, | ||
IPEndPoint | source, | ||
IPEndPoint | receivedAt | ||
) |
Handle a SUCCESS_RESPONSE Message from the Stun server
Messages whose transaction ID do not match an open Transaction are ignored. Valid messages are passed to the onComplete handler of the corresponding Transaction.
message | |
transaction |
void NobleConnect.Stun.Controller.HandleResponse | ( | Transaction< Message > | transaction, |
Message | response, | ||
IPEndPoint | source, | ||
IPEndPoint | receivedAt | ||
) |
void NobleConnect.Stun.Controller.HandleSuccessResponse | ( | Transaction< Message > | transaction, |
Message | response, | ||
IPEndPoint | source, | ||
IPEndPoint | receivedAt | ||
) |
Handle a SUCCESS_RESPONSE Message from the Stun server
Messages whose transaction ID do not match an open Transaction are ignored. Valid messages are passed to the onComplete handler of the corresponding Transaction.
response | |
transaction |
void NobleConnect.Stun.Controller.OnBindComplete | ( | Transaction< Message > | transaction, |
Action< Transaction< Message >> | callback = null , |
||
Action< Transaction< Message >> | errorCallback = null |
||
) |
void NobleConnect.Stun.Controller.QueueRebind | ( | IPEndPoint | target, |
IPEndPoint | source | ||
) |
Message NobleConnect.Stun.Controller.ReadMessage | ( | byte[] | buffer, |
ref int | bufferIndex, | ||
int | bufferLength | ||
) |
void NobleConnect.Stun.Controller.ReceiveBytes | ( | byte[] | buffer, |
int | index, | ||
int | count, | ||
IPEndPoint | source, | ||
IPEndPoint | receivedAt, | ||
bool | fromRelay | ||
) |
void NobleConnect.Stun.Controller.ReSend | ( | Transaction< Message > | transaction | ) |
Re-send a request from a failed transaction
transaction |
void NobleConnect.Stun.Controller.RevokeAllBindings | ( | ) |
void NobleConnect.Stun.Controller.RevokeBinding | ( | IPEndPoint | target, |
IPEndPoint | source | ||
) |
Transaction<Message> NobleConnect.Stun.Controller.Send | ( | Message | message, |
IPEndPoint | target, | ||
IPEndPoint | source, | ||
IPEndPoint | associatedAllocation = null , |
||
Action< Transaction< Message >> | onResponse = null , |
||
Action< Transaction< Message >> | onFail = null , |
||
int | overrideMaxResend = -1 , |
||
int | overrideTimeout = -1 |
||
) |
Send a message to the Stun server. Optionally call onResponse when a response is received.
This method automatically adds a Transaction for the message if it is a request.
message | |
onResponse |
void NobleConnect.Stun.Controller.SendBindErrorResponse | ( | IPEndPoint | target, |
IPEndPoint | receivedAt, | ||
Message | request | ||
) |
void NobleConnect.Stun.Controller.SendBindIndication | ( | IPEndPoint | target, |
IPEndPoint | source | ||
) |
void NobleConnect.Stun.Controller.SendBindRequest | ( | Action< Transaction< Message >> | onBindComplete, |
Action< Transaction< Message >> | onBindError | ||
) |
void NobleConnect.Stun.Controller.SendBindRequest | ( | Action< Transaction< Message >> | onBindComplete, |
Action< Transaction< Message >> | onBindError, | ||
List< Attribute > | attributes, | ||
IPEndPoint | target, | ||
IPEndPoint | source, | ||
int | overrideMaxResend = -1 |
||
) |
Send a Bind Request to the Stun server. Call onBindComplete when the Response is received.
onBindComplete |
void NobleConnect.Stun.Controller.SendBindSuccessResponse | ( | IPEndPoint | target, |
IPEndPoint | receivedAt, | ||
Message | request | ||
) |
void NobleConnect.Stun.Controller.SendErrorResponse | ( | MessageMethod | method, |
ushort | errorCode, | ||
string | errorMessage, | ||
IPEndPoint | target, | ||
IPEndPoint | receivedAt, | ||
Message | request | ||
) |
bool NobleConnect.Stun.Controller.SendMessage | ( | Message | message, |
IPEndPoint | target, | ||
IPEndPoint | source | ||
) |
Transaction<Message> NobleConnect.Stun.Controller.SendRequest | ( | Message | message, |
IPEndPoint | target, | ||
IPEndPoint | source, | ||
IPEndPoint | associatedAllocation = null , |
||
Action< Transaction< Message >> | onResponse = null , |
||
Action< Transaction< Message >> | onFail = null , |
||
int | overrideMaxResend = -1 , |
||
int | overrideTimeout = -1 |
||
) |
void NobleConnect.Stun.Controller.SocketSend | ( | byte[] | data, |
int | offset, | ||
int | count, | ||
IPEndPoint | destination | ||
) |
bool NobleConnect.Stun.Controller.ValidateMessage | ( | Message | request, |
byte[] | buffer | ||
) |
object NobleConnect.Stun.Controller.bandwidthLock = new object() |
Timer NobleConnect.Stun.Controller.bandwidthTimer |
int NobleConnect.Stun.Controller.bandwidthUsedThisSecond = 0 |
|
static |
How often to refresh bindings
Bindings do not last forever on nat devices, so they must be refreshed periodically. RFC 4787 Section 12 REQ-5 specifies that bindings must not expire in less than 2 minutes, so as long as this refresh time is less than 2 minutes it is guaranteed that bindings will stay alive on any complient nat device.
BufferPool NobleConnect.Stun.Controller.bufferPool |
readonly ControllerConfig NobleConnect.Stun.Controller.config |
|
static |
|
static |
|
static |
|
static |
This is the same thing as the COOKIE but stored in network byte order.
We pre-compute this one time in the static constructor since it will never change.
Dictionary<IPSet, Credentials> NobleConnect.Stun.Controller.credentialsForEndPoint = new Dictionary<IPSet, Credentials>() |
The set of credentials to send with Requests that requires authentication.
Dictionary<string, Credentials> NobleConnect.Stun.Controller.localCredentials = new Dictionary<string, Credentials>() |
The credentials to use when authenticating requests made to this client.
readonly IPEndPoint NobleConnect.Stun.Controller.localEndPoint |
DataHandler NobleConnect.Stun.Controller.multiplexedDataHandler |
The DataHandler to use for handling multiplxed data
readonly TransactionList<Message> NobleConnect.Stun.Controller.openTransactions = new TransactionList<Message>() |
byte [] NobleConnect.Stun.Controller.receiveBuffer = new byte[4096] |