pub struct Registration {
pub last_seq: u32,
pub endpoint: EndpointInnerRef,
pub credential: Option<Credential>,
pub contact: Option<Contact>,
pub allow: Allow,
pub public_address: Option<HostWithPort>,
}Expand description
SIP Registration Client
Registration provides functionality for SIP user agent registration
with a SIP registrar server. Registration is the process by which a
SIP user agent informs a registrar server of its current location
and availability for receiving calls.
§Key Features
- User Registration - Registers user agent with SIP registrar
- Authentication Support - Handles digest authentication challenges
- Contact Management - Manages contact URI and expiration
- DNS Resolution - Resolves registrar server addresses
- Automatic Retry - Handles authentication challenges automatically
§Registration Process
- DNS Resolution - Resolves registrar server address
- REGISTER Request - Sends initial REGISTER request
- Authentication - Handles 401/407 challenges if needed
- Confirmation - Receives 200 OK with registration details
- Refresh - Periodically refreshes registration before expiration
§Examples
§Basic Registration
let credential = Credential {
username: "alice".to_string(),
password: "secret123".to_string(),
realm: Some("example.com".to_string()),
};
let mut registration = Registration::new(endpoint.inner.clone(), Some(credential));
let server = rsip::Uri::try_from("sip:sip.example.com").unwrap();
let response = registration.register(server.clone(), None).await?;
if response.status_code == rsip::StatusCode::OK {
println!("Registration successful");
println!("Expires in: {} seconds", registration.expires());
}
}§Registration Loop
let mut registration = Registration::new(endpoint.inner.clone(), Some(credential));
loop {
match registration.register(server.clone(), None).await {
Ok(response) if response.status_code == rsip::StatusCode::OK => {
let expires = registration.expires();
println!("Registered for {} seconds", expires);
// Re-register before expiration (with some margin)
tokio::time::sleep(Duration::from_secs((expires * 3 / 4) as u64)).await;
},
Ok(response) => {
eprintln!("Registration failed: {}", response.status_code);
tokio::time::sleep(Duration::from_secs(30)).await;
},
Err(e) => {
eprintln!("Registration error: {}", e);
tokio::time::sleep(Duration::from_secs(30)).await;
}
}
}§Thread Safety
Registration is not thread-safe and should be used from a single task. The sequence number and state are managed internally and concurrent access could lead to protocol violations.
Fields§
§last_seq: u32§endpoint: EndpointInnerRef§credential: Option<Credential>§contact: Option<Contact>§allow: Allow§public_address: Option<HostWithPort>Public address detected by the server (IP and port)
Implementations§
Source§impl Registration
impl Registration
Sourcepub fn new(endpoint: EndpointInnerRef, credential: Option<Credential>) -> Self
pub fn new(endpoint: EndpointInnerRef, credential: Option<Credential>) -> Self
Create a new registration client
Creates a new Registration instance for registering with a SIP server. The registration will use the provided endpoint for network communication and credentials for authentication if required.
§Parameters
endpoint- Reference to the SIP endpoint for network operationscredential- Optional authentication credentials
§Returns
A new Registration instance ready to perform registration
§Examples
// Registration without authentication
let registration = Registration::new(endpoint.inner.clone(), None);
// Registration with authentication
let credential = Credential {
username: "alice".to_string(),
password: "secret123".to_string(),
realm: Some("example.com".to_string()),
};
let registration = Registration::new(endpoint.inner.clone(), Some(credential));Sourcepub fn discovered_public_address(&self) -> Option<HostWithPort>
pub fn discovered_public_address(&self) -> Option<HostWithPort>
Get the discovered public address
Returns the public IP address and port discovered during the registration process. The SIP server indicates the client’s public address through the ‘received’ and ‘rport’ parameters in Via headers.
This is essential for NAT traversal, as it allows the client to use the correct public address in Contact headers and SDP for subsequent dialogs and media sessions.
§Returns
Some((ip, port))- The discovered public IP address and portNone- No public address has been discovered yet
§Examples
if let Some(public_address) = registration.discovered_public_address() {
println!("Public address: {}", public_address);
// Use this address for Contact headers in dialogs
} else {
println!("No public address discovered yet");
}Sourcepub fn expires(&self) -> u32
pub fn expires(&self) -> u32
Get the registration expiration time
Returns the expiration time in seconds for the current registration. This value is extracted from the Contact header’s expires parameter in the last successful registration response.
§Returns
Expiration time in seconds (default: 50 if not set)
§Examples
let expires = registration.expires();
println!("Registration expires in {} seconds", expires);
// Schedule re-registration before expiration
let refresh_time = expires * 3 / 4; // 75% of expiration time
tokio::time::sleep(Duration::from_secs(refresh_time as u64)).await;Sourcepub async fn register(
&mut self,
server: Uri,
expires: Option<u32>,
) -> Result<Response>
pub async fn register( &mut self, server: Uri, expires: Option<u32>, ) -> Result<Response>
Perform SIP registration with the server
Sends a REGISTER request to the specified SIP server to register the user agent’s current location. This method handles the complete registration process including DNS resolution, authentication challenges, and response processing.
§Parameters
server- SIP server hostname or IP address (e.g., “sip.example.com”)
§Returns
Ok(Response)- Final response from the registration serverErr(Error)- Registration failed due to network or protocol error
§Registration Flow
- DNS Resolution - Resolves server address and transport
- Request Creation - Creates REGISTER request with proper headers
- Initial Send - Sends the registration request
- Authentication - Handles 401/407 challenges if credentials provided
- Response Processing - Returns final response (200 OK or error)
§Response Codes
200 OK- Registration successful401 Unauthorized- Authentication required (handled automatically)403 Forbidden- Registration not allowed404 Not Found- User not found423 Interval Too Brief- Requested expiration too short
§Examples
§Successful Registration
let server = rsip::Uri::try_from("sip:sip.example.com").unwrap();
let response = registration.register(server, None).await?;
match response.status_code {
rsip::StatusCode::OK => {
println!("Registration successful");
// Extract registration details from response
if let Ok(_contact) = response.contact_header() {
println!("Registration confirmed");
}
},
rsip::StatusCode::Forbidden => {
println!("Registration forbidden");
},
_ => {
println!("Registration failed: {}", response.status_code);
}
}§Error Handling
match registration.register(server, None).await {
Ok(response) => {
// Handle response based on status code
},
Err(Error::DnsResolutionError(msg)) => {
eprintln!("DNS resolution failed: {}", msg);
},
Err(Error::TransportLayerError(msg, addr)) => {
eprintln!("Network error to {}: {}", addr, msg);
},
Err(e) => {
eprintln!("Registration error: {}", e);
}
}§Authentication
If credentials are provided during Registration creation, this method will automatically handle authentication challenges:
- Send initial REGISTER request
- Receive 401/407 challenge with authentication parameters
- Calculate authentication response using provided credentials
- Resend REGISTER with Authorization header
- Receive final response
§Contact Header
The method will automatically update the Contact header with the public address discovered during the registration process. This is essential for proper NAT traversal in SIP communications.
If you want to use a specific Contact header, you can set it manually before calling this method.
Sourcepub fn create_nat_aware_contact(
username: &str,
public_address: Option<HostWithPort>,
local_address: &SipAddr,
) -> Contact
pub fn create_nat_aware_contact( username: &str, public_address: Option<HostWithPort>, local_address: &SipAddr, ) -> Contact
Create a NAT-aware Contact header with public address
Creates a Contact header suitable for use in SIP dialogs that takes into account the public address discovered during registration. This is essential for proper NAT traversal in SIP communications.
§Parameters
username- SIP username for the Contact URIpublic_address- Optional public address to use (IP and port)local_address- Fallback local address if no public address available
§Returns
A Contact header with appropriate address for NAT traversal
§Examples
let contact = Registration::create_nat_aware_contact(
"alice",
Some(rsip::HostWithPort {
host: IpAddr::V4(Ipv4Addr::new(203, 0, 113, 1)).into(),
port: Some(5060.into()),
}),
&local_addr,
);