#include <RouteState.h>
The sipXauthproxy uses this class to encode state information to be carried by the request messages in a dialog. Normally, this class is used only by an AuthPlugin object in its implementation of AuthPlugin::authorizeAndModify.
State is encoded as name/value pairs. The name is composed of two parts, each of which may consist only of A-Z, a-z, 0-9, underscore (_), and dash (-).:
Obeying this naming convention ensures that an AuthPlugin will not unintentionally access or modify state for some other AuthPlugin. If the AuthPlugin uses only one parameter, it may pass an empty string for the parameterName.
The state in a message is 'signed' by a hash value that incorporates a secret (see setSecret); this signature binds the message to the call-id and from-tag values from the dialog-forming request. A state value whose hash value does not match is logged, but is otherwise equivalent to a message for which no state was received (no parameter names or values are available).
State can only be created (encoded) in the initial dialog-forming request message; in subsequent in-dialog requests and in responses, the state can be decoded and read, but cannot be modified. This is because the state is encoded into a route inserted into a Record-Route: the route set for the dialog is established by the Record-Route header(s) in the request/response messages that create the dialog. Subsequent messages in the dialog carry those values in Route headers, but they cannot be changed. To determine whether state can be changed, call isMutable.
The SIP protocol allows a proxy to modify the Record-Route headers in the dialog-forming response so that the two ends of the dialog see different route sets. However, the current sipXtackLib design proxies responses before sending them to the application (sipXauthproxy) layer, so we must use symetric state. (There are some protocol problems with modifying responses anyway, since in the case of SUBSCRIBE or other requests that can create multiple dialogs, the requestor may not see all responses, but because of the stack limitation this is moot for us)
To access the state in a message, construct a RouteState object, passing the message and any Route headers removed by SipMessage::normalizeProxyRoutes to the constructor. SipRouter::proxyMessage uses the update method to put the updated state back into the message.
A dialog-forming request that passes through the same sipXauthproxy more than once (spirals) will not get multiple Record-Route headers. The first spiral to call the 'update' method adds a Record-Route; subsequent calls modify the state information recorded in that existing header so that in-dialog requests only traverse this proxy once.
Decoding Operations | |
| These methods access the state in a message. | |
| RouteState (const SipMessage &message, const UtlSList &removedRoutes, const UtlString routeName) | |
| Decode the route state for a received message. | |
| bool | getParameter (const char *pluginInstance, const char *parameterName, UtlString ¶meterValue) const |
| Extract value of a parameter saved in the route state. | |
| bool | directionIsCallerToCalled (const char *instanceName) |
| Used to discover the request direction. | |
| bool | originalCallerFromTagValue (const char *instanceName, UtlString &fromTagValue) |
| Returns the from tag value of the dialog forming request. | |
| void | markDialogAsAuthorized (void) |
| Adds an encoded parameter to a mutable RouteState indicating that the dialog is authorized. | |
| bool | isDialogAuthorized (void) |
| used to discover whether or not the dialog has already been authorized. | |
Encoding Operations | |
| These methods manipulate the state encoded into a dialog-forming request. | |
| bool | isMutable () |
| Is it possible to record state in this request? | |
| bool | isFound () |
| void | setParameter (const char *pluginInstance, const char *parameterName, const UtlString ¶meterValue) |
| Stores the value of a parameter in the route state. | |
| void | unsetParameter (const char *pluginInstance, const char *parameterName) |
| Removes any value for a parameter from the route state. | |
| void | addCopy (void) |
| The addCopy method is used to add another Record-Route w/ a RouteState to a request that already has one. | |
| void | update (SipMessage *request) |
| Add or update the state in the Record-Route header. | |
| static void | setSecret (const char *secret) |
| Initialize the secret value used to sign RouteState information. | |
Public Member Functions | |
| ~RouteState () | |
| destructor | |
Protected Member Functions | |
| void | encode (UtlString &stateToken) |
| Encode and sign the state as a single SIP token. | |
| bool | decode (const UtlString &stateToken) |
| Check the signature and parse the name/value pairs from a state token. | |
Private Attributes | |
| UtlString | mRouteHostPort |
| hostport value to use when adding Record-Route headers | |
| bool | mMayBeMutable |
true iff
| |
| std::vector< size_t > | mRecordRouteIndices |
| Used only if mMayBeMutable == true This is a list of Record-Route header indices that contain a hostport matching the mRouteHostPort. | |
| bool | mModified |
| Used only if mMayBeMutable == true Tracks whether or not any changes have been made to the state, so that we know whether or not to rewrite it in the update method. | |
| bool | mFoundRouteState |
| Indicates if a RouteState has been found in the route set supplied at construction time. | |
| bool | mAddCopyRequested |
| UtlSortedList | mValues |
| contains NameValuePair objects | |
| UtlString | mCallId |
| UtlString | mFromTag |
Static Private Attributes | |
| static const char * | UrlParameterName = "sipXecs-rs" |
| static UtlString | mSignatureSecret |
Friends | |
| class | RouteStateTest |
| RouteState | ( | const SipMessage & | message, | |
| const UtlSList & | removedRoutes, | |||
| const UtlString | routeName | |||
| ) |
Decode the route state for a received message.
This method must be called after the received request has been normalized by normalizeProxyRoutes.
| message | normalized incoming message |
| removedRoutes | removed routes returned by normalizeProxyRoutes |
| routeName |
The SIP address to use in the added route. It may include only:
|
| ~RouteState | ( | ) |
destructor
| bool getParameter | ( | const char * | pluginInstance, | |
| const char * | parameterName, | |||
| UtlString & | parameterValue | |||
| ) | const |
Extract value of a parameter saved in the route state.
| parameterValue | output |
| bool directionIsCallerToCalled | ( | const char * | instanceName | ) |
Used to discover the request direction.
| instanceName | used for logging - must not be null |
| bool originalCallerFromTagValue | ( | const char * | instanceName, | |
| UtlString & | fromTagValue | |||
| ) |
Returns the from tag value of the dialog forming request.
Do not use as a substitute for directionIsCallerToCalled
| instanceName | used for logging - must not be null |
| void markDialogAsAuthorized | ( | void | ) |
Adds an encoded parameter to a mutable RouteState indicating that the dialog is authorized.
Authorizating entities can test for the presence of such a parameter using the RouteState::isDialogAuthorized() method when processing requests.
| bool isDialogAuthorized | ( | void | ) |
used to discover whether or not the dialog has already been authorized.
Some AuthPlugin classes need to make different changes to a request depending on whether it was sent from the original caller or the called party. For example, anything that makes changes to the To or From headers needs to know which is which because they will be swapped for an in-dialog request sent by the called party. This method provides a uniform way to discover this.
This caches the From tag from the original caller in a shared parameter in the RouteState (a shared parameter passes null string for the instanceName) so that once it is computed by any plugin it is accessible to all.
| bool isMutable | ( | ) | [inline] |
Is it possible to record state in this request?
<
| bool isFound | ( | ) | [inline] |
| void setParameter | ( | const char * | pluginInstance, | |
| const char * | parameterName, | |||
| const UtlString & | parameterValue | |||
| ) |
Stores the value of a parameter in the route state.
Establish a new value for the named parameter to be included when the updated route state is generated.
A parameter may be set to the null (zero length) value.
| void unsetParameter | ( | const char * | pluginInstance, | |
| const char * | parameterName | |||
| ) |
Removes any value for a parameter from the route state.
This removes the named parameter from those included when the updated route state is recorded.
| void addCopy | ( | void | ) |
The addCopy method is used to add another Record-Route w/ a RouteState to a request that already has one.
The logic here ensures that all copies of the RouteState contain all the same parameters and that they remain synchronized.
| void update | ( | SipMessage * | request | ) |
Add or update the state in the Record-Route header.
This has no effect other than logging an error if isMutable would return false.
| request | message to add state too, if state was modified |
| void setSecret | ( | const char * | secret | ) | [static] |
Initialize the secret value used to sign RouteState information.
Initialize the secret value used to sign hashes.
This must be called once at initialization time, before any RouteState objects are created.
It may be called after that, but doing so with a new value will invalidate any outstanding route state.
| secret |
a null terminated string used as input to sign the state value. This should be chosen such that it:
|
| void encode | ( | UtlString & | stateToken | ) | [protected] |
Encode and sign the state as a single SIP token.
| bool decode | ( | const UtlString & | stateToken | ) | [protected] |
Check the signature and parse the name/value pairs from a state token.
friend class RouteStateTest [friend] |
const char * UrlParameterName = "sipXecs-rs" [static, private] |
UtlString mRouteHostPort [private] |
hostport value to use when adding Record-Route headers
bool mMayBeMutable [private] |
true iff
std::vector<size_t> mRecordRouteIndices [private] |
Used only if mMayBeMutable == true This is a list of Record-Route header indices that contain a hostport matching the mRouteHostPort.
These Record-Route headers may or may not contain Route State parameters.
bool mModified [private] |
Used only if mMayBeMutable == true Tracks whether or not any changes have been made to the state, so that we know whether or not to rewrite it in the update method.
bool mFoundRouteState [private] |
Indicates if a RouteState has been found in the route set supplied at construction time.
bool mAddCopyRequested [private] |
UtlSortedList mValues [private] |
contains NameValuePair objects
UtlString mSignatureSecret [static, private] |