In the previous article Third-Party Video Conferencing with Lync the concepts of the Lync Server Trusted Applications and Static Routing were discussed in relation to supporting video calls with external third-party solutions. The static routing configuration was then expanded upon in another more recent article. The following article will explain the concept of the MatchURI parameter and the different options available when selecting a value for new static routes in Lync Server, detailing the unique benefits of each approach.
Background
The MatchURI parameter is an option available in the New-CsStaticRoute cmdlet in Lync Server which is used to define either a specific Fully Qualified Domain Name (e.g. hostname.domain.com) or simply a domain name (e.g. domain.com) in which Lync will use to identify traffic that must be routed to foreign applications. Alternatively a wildcard entry is also valid (e.g. *.domain.com) which would be used to mask traffic to any string which appears to look like either an FQDN or subdomain in the parent namespace.
It is important to understand that the MatchURI value does not need to be resolvable in terms of DNS or any other name resolution protocol. If an FQDN is used there is no need to define that FQDN in DNS as the static routing entry in Lync is what defines the mapping of a MatchURI string to a destination host. What is critical is that the Destination parameter, which must be a valid host FQDN for TLS routes (TCP routes can only use an IP address here), is resolvable by the Lync server. This is commonly misunderstood as often the Destination and MatchURI values are set to the same string and administrators assume that the MatchURI needs to be resolvable outside of Lync.
The example below would be used to create a new static route in Lync which would define that any messages to SIP addresses in the video.mslync.net namespace should be routed to an application running on the defined host.
$route = New-CsStaticRoute -TLSRoute -Destination "appserver1.schertz.name" -Port 5061
-MatchUri "video.mslync.net" -UseDefaultCertificate $TrueSet-CsStaticRoutingConfiguration -Identity global -Route @{Add=$route}
Note that a user-friendly MatchURI is selected instead of a potentially confusing-looking server FQDN. When the AD namespace is different than the SIP domain namespace this approach is even more important as regular users need not be burdened with handling different namespaces in Lync.
As pointed out in previous articles this new static route cannot be used alone, to function there must also be a configured Trusted Application with the same destination and port so that Lync will allow communications to and from the defined host(e.g. appserver1.schertz.name).
Also mentioned in a previous article is that the MatchURI value must be unique within a defined routing collection or container as Lync Server will only use the first rule it finds where the MatchURI parameter matches.
Routing Behavior
When a request is sent from a Lync client to a specific SIP URI the Lync server will decide where it needs to forward the message to and will do so by following a specific order of logic.
Local
Lync first checks to see if the SIP URI belongs to another internal Lync user defined in the same environment. Note that this has nothing to do with whether the Lync user is actively registered from an internal or external network. The term local in this context means that the target SIP URI is defined within Active Directory and belongs to some entity owned by this Lync Server environment, like a registered Lync user or contact.
INVITE sip: jeff@mslync.net SIP/2.0
Text: Routed a locally generated response
SIP-Start-Line: SIP/2.0 100 Trying
Peer: lync.schertz.name:60988
Registered Application
Any trusted host or application which is capable of natively registering a Lync user account directly would also be included in this category. Although the SIP address is defined within Active Directory when that user is not registered using a native Lync client but instead via a trusted application or contact then the message is routed on behalf of an application. Understand that a static route is not applicable here as the endpoint is actively registered; note the random port of 60000.
INVITE sip: vmr1@mslync.net SIP/2.0
Text: Routed a request on behalf of an application
SIP-Start-Line: INVITE sip:vmr1@192.168.1.13:60000;transport=tls;ms-received-cid=DC6000 SIP/2.0
Peer: rmx.schertz.name:60000
Unregistered Application
Other types of trusted applications which do not actually register on behalf of defined Lync users can still send and receive SIP messages. Presence and other Lync capabilities would not be available, but any static route defined in Lync would be used to direct traffic to these hosts.
INVITE sip:71503@video.mslync.net SIP/2.0
Text: Routed a request to an internal server or static route
SIP-Start-Line: INVITE sip:71503@video.mslync.net SIP/2.0
Peer: dma.schertz.name:5061
Federation
If Lync is unable to locate the SIP URI in its own database of defined objects and routes then the next place it would look is to see if the domain name is manually defined somewhere with an external destination. This would include federated partner domains which are manually defined.
INVITE sip: lyncuser@partnerdomain.com SIP/2.0
Text: Routed a request towards the edge of the enterprise
SIP-Start-Line: INVITE sip:lyncuser@partnerdomain.com SIP/2.0
Peer: edge.schertz.name:5061
Open Federation
In the event that Lync cannot resolve either the SIP URI exactly or perform a domain name match then it will assume the domain name is an undefined external deployment and then route the message to the Edge Server to perform an SRV lookup for an Open Federation service locator record in DNS. If no record is found then the message will have no where to go and the Lync client will report that the target address cannot be resolved.
INVITE sip: no-one@nowhere.com SIP/2.0
ms-diagnostics: 1008 reason="Unable to resolve DNS SRV record"; domain="nowhere.com";source="sip.schertz.name"
Options
Based on these different routing options it should be clear that the MatchURI defined on static routes needs to fit into the overall configuration without overlapping or impacting other potential routes. There are some basic requirements which should be understood when deciding what matching string to use when creating a static route.
Shared Namespace
As of Lync 2010 it is possible to use a defined SIP domain also as a MatchURI value. Meaning that if the primary SIP domain, or any defined secondary SIP domain, was something like mslync.net then that exact same domain name could be configured as the MatchURI.
$route = New-CsStaticRoute -TLSRoute -Destination "trustedhost1.schertz.name" -Port 5061 -MatchUri "mslync.net" -UseDefaultCertificate $True
Set-CsStaticRoutingConfiguration -Identity global -Route @{Add=$route}
This approach is the most straightforward and provides for a couple advantages in terms of configuration simplicity, yet will also create a situation where all unresolved SIP requests in the namespace will no longer be rejected by the Lync server and instead will be forwarded on to the trusted application host.
Unique Namespace
The alternative method is to define an unique value as the MatchURI. This can be something as simple as selecting a simple prefix to appear like a subdomain (e.g. video.mslync.net), using something that doesn’t even look like a domain name (e.g. video), or using the same value as the FQDN of the target host (e.g. trustedhost1.schertz.name). Selecting a subdomain-like string is ideal as it dedicates that namespace to the application and creates a boundary for traffic. Not all applications are compatible with short names so these are typically not avoided. Using the application server’s hostname is never recommended as these are typically confusing to users and often times are defined in a different namespace defined for Active Directory which is not the same as the SIP domain.
The example below uses a simple string which although it may look like a sub-domain name or Host FQDN, it is actually neither. It is simply a string used to match against SIP URIs. There are no records or zones defined in DNS to coincide with ‘video.mslync.net’ as this name exists only within the Lync Server configuration.
$route = New-CsStaticRoute -TLSRoute -Destination "trustedhost1.schertz.name" -Port 5061 -MatchUri "video.mslync.net" -UseDefaultCertificate $True
Set-CsStaticRoutingConfiguration -Identity global -Route @{Add=$route}
This approach may require a few additional steps when dealing with federated access but will segregate traffic for the specific application and greatly reduce the amount of requests which Lync routes out to the external host.
As mentioned earlier whatever the value selected for the MatchURI there is no need to define it in DNS so make it as simple as possible. It is usually best to use a descriptive prefix with an existing SIP domain, as long as that prefix is not already defined as a real sub-domain namespace in DNS.
Comparison
The underlying lesson in this article is that there is no single best-practice for selecting a MatchURI value as each approach has its merits and drawbacks which can differ based on the environment and desired results. The following sections explain the behavior of each option so that one may decide which is best for each specific deployment.
SIP Traffic Impact
When using a shared namespace directing calls to an application would be as simple as typing or clicking on SIP URIs which appear to look like any other SIP URI from the organization. To call a Lync user named Steve one would simply enter something like “steve@mslync.net” and to place a video call to third-party conferencing bridge with the meeting number of 71234 the user would simply enter “71234@mslync.net” into the Lync client.
Unfortunately because this approach will send every SIP request to the application that Lync is unable to resolve then the application could potentially receive a lot of unwanted traffic. For example if a previously enabled Lync user account was still on another user’s contact list, although it had been deleted from Active Directory the Lync client would still send SIP SUBSCRIBE messages to the server to request the latest presence status of that user. Normally the Lync server would respond back to the client that the address was not found and that would be the end of that request. But when a static route sharing the SIP domain is defined then after the Lync server is unable to resolve the target SIP URI it will then forward the request on to the application defined in the static route.
The following example shows how Lync server will forward a presence status request for an unresolved SIP URI to the application, even though that application may not even support this type of request, hence the 489 Bad Event response from the application to the Lync server.
Although this one event may not seem like much imagine how many unwanted requests may be forwarded to an application in a large production environment where multiple scenarios can trigger events like these. Think about what would happen in the case that a user were to send an email to a very large distribution list with SMTP recipients like ‘hr@company.com’ or ‘sales@company.com’. When every recipient views that message in Outlook their Lync clients will attempt to light up the presence icon in their window, sending requests to the server for these addresses. Clearly those addresses are not Lync users but simply Exchange mailboxes or distribution lists in the same domain namespace. But because Lync now shares that namespace with another SIP application it will forward every one of these unresolved requests on the application even if that application doesn’t even want them or know what to do with them. Then add in all the mistyped SIP addresses, outdated contacts stored on user’s contact lists, etc.
In general using a shared namespace is fine for small production deployments or test/pilot environments but the larger the environment the more this extra traffic can place an unnecessary load on both sides of the route. Utilizing a unique namespace as the MatchURI would eliminate this behavior altogether.
Lync Federation
A benefit of the shared namespace scenario is that federated users can also utilize the application if the SIP domain is already configured for federation. The federated user would place a call to the same “71234@mslync.net” SIP URI in which their Lync server would route to the same Edge Server as any call for that SIP domain. Once the message is received by the target Lync environment it would locate the defined static route just the same as if the call came from a local Lync user.
The ease of allowing federated traffic into an application from external parties by using a shared namespace may actually be looked upon as a disadvantage as it may be desired to limit the access to the application to only local users or possibly just a subset of federated users. In this case using a unique namespace can be ideal as then federated access can be completely prevented, or configured for only specific partners. To allow specific partners to send calls to the application simply define the chosen MatchURI (e.g. video.mslync.net) as a secondary SIP domain in Lync and then configured Federation with the desired partners manually. This will allow remote Edge servers to route calls to that domain as if it were a SIP domain so that the requests will land on the appropriate Edge server, which will then forward the request to the internal Lync servers which are aware of the defined static route for that namespace.
This secondary SIP domain name does not need to be reflected on any server certificates as either Open or Manual Federation would be configured such that the partner domain would point to the same Access Edge FQDN that the other SIP domains in that organization already use.
- Using the example above the Lync Server Topology would be configured to define an additional supported SIP domain using the same string as the Match URI (e.g. video.mslync.net).
- Then a federated partner would then simply add a new Allowed Domain to their Lync Server configuration using the same Access Edge FQDN (e.g. sip.mslync.net) which is already in place for the default SIP domain.
- To additionally support Open Federation for the new namespace a new Lync Federation Service Record (SRV) can be created and pointed to the same pre-existing Access Edge FQDN.
_sipfederationtls._tcp.video.mslync.net SRV service location:
priority = 0
weight = 1
port = 5061
svr hostname = sip.mslync.net
Lync Online Hybrid Deployments
When working with Office 365 Hybrid Deployments then using the SIP domain name for a trusted application route is not an option. The defined SIP domain is used to establish the split-domain configuration between an on-premises Lync Server 2013 deployment and the Office 365-hosted Lync Online environment.
In this scenario a unique namespace must be chosen for the MatchURI for any static routes.
[…] http://blog.schertz.name/2013/09/selecting-matchuri-lync/ […]
Hi Jeff,
Great article. Im currently troubleshooting a problem which i believe may be related the the SIP routing, but i cant be sure and would appreciate your insight.
Essentially we have a hybrid (On-Premise v. Online) configuration where an Online user is unable to communicate with an on-premise user (different federated domains). The symptoms are strange in as much as, if the on-premise user initiates the conversation the On-line user can reply, but not the other way around. More worrying is i personally do not have this issue with the online account and our two on-premise accounts are in the same domain and look identically configured. The SIPStack trace throws “Not Acceptable Here” and a “Trying” error when attempting to establish communications with the troubleshome account, but again with my account i see it SIP routing go through without issues.
Any suggestions what might be causing this split routing issue?
Thanks
From your description it doesn’t sound like you are testing video interop but you cannot use a SIP domain as a MatchURI for any static routes in a Hybrid (SPlit-Domain) deployment.
Hi Jeff,
does the restriction (“but you cannot use a SIP domain as a MatchURI “) also apply for a secondary SIP domain in a Skype Hybrid environment? The secondary SIP domain would point to the Skype Edge for federated partner to connect to Poly static VMRs. The same secondary SIP domain would be configured as match Match URI for a trusted application route.
Would that work?
Does the secondary domain need to be configured as split domain in Skype Online too?
Are there certificates needed on the Skype Edge for the secondary domain?
Thanks,
Bob
As long as the domain name is NOT configured for Split-Domain Hybrid use with SfB Online then it should be fine. Secondary SIP domains usually are not used on the Edge server’s public certs, just the primary SIP domain.
Hi Jeff,
For testing purpose we created two meeting rooms,
First one with sip:rmx9001@domain.com like any regular user. Subsequent meeting rooms was created on RMX with SIP Registration checked.
Server IP Address or Name: FEPool.Domain.com
Server Domain Name: Domain.com
Port: 5061
It was able to register and presence started showing up, everything started working as expected, however after the test we removed the meeting room completely from RMX. Now while an enabled user account sip:rmx9001@domain.com do exist in Lync, it is logged in nowhere. However, whoever contacted this RMX user or added to their Lync contacts still sees it as green (Available), although when they attempt to start a video, they gets error message that user is offlice. I wonder how/when lync clients will reports this as offline or unavailable?
Sometimes if you just delete a meeting room with first unregistering it in the RMX then presence is not update and will be stuck as online until the Lync Server is rebooted. You should change the Conference Profile in the registered meeting room to something like the default profile to trigger the RMX to unregister the room in Lync, then you can delete it from the RMX. This was addressed in more current versions of the RMX firmware so I'm guessing you are running an older release version.
Second with sip:rmx9002@video.domain.com via static route method. Please note that it won't let me enable a user untill I added adddtional supported SIP domain i.e Video.Domain.com in topology builder, followed by publishing topology and updating FE servers in pool. Subsequent meeting room was created on RMX with SIP Registration checked, again. This time the config on RMX meeting rooms was as follows
Server IP Address or Name: FEPool.domain (yes it is same)
Server Domain Name: Video.Domain.com
Port: 5061
This one is doing the same thing the presence information is not changing. It shows on either Available/Busy when dialed, but not offline or unknown, even when it doesn't exist on RMX? any reason why?
When using Static Routes you cannot define SIP-enabled user objects in AD/Lync using those SIP URIs. This method is completely different than the registered room method in the RMX and you cannot mix the two. You shouldn't be deviating from the official deployment documentation.
Hi Jeff,
My I've created my certificate and trusted application pool and insert server but could not make a call through.
My question is, I only generated the certificate shared with the DMA on one front end server and not my other two servers, do I need to import to all my frontend servers or one is fine?
second, I tried calling one of the DMA numbers and my call stays for about 2 minute and late reply with CALL WAS UNSUCCESSFULL.
Please what can I do in this situation?
Thanks
The DMA certificate only needs to be installed on the DMA, there is no need to have it saved on the Lync servers. The Lync server was only used to generate the original certificate request as using the Windows server tools is easier; you can delete it from the original server once you have the issued certificate and private key exported and saved into a PFX file. Does the call ring for 2 minutes and fail, or complete and then drop after 2 minutes?
Hi Jeff,
I’m struggling with static route.. I set a static global TLS-Route to match URI VC.Domain.com.
Next hop is my CISCO VCS. Calls to CISCO EQ are working fine from users who are registered at central pool. If I do the same in the branch the call ends in SIP404 – ms-diagnostics: 1008;reason=”Unable to resolve DNS SRV record”
Instead of routing the call to VCS I see my EdgeServer in the game. Now i set also are sattic-route on registrar-level for the branch, but that changes nothing. Any Idea.
Regards Timo
I have seen this intermittently in Lync but not in a scenario where one pool works and another does not. the configuration is topology-wide so the global route should work for all pools the same. I would try defining the same route separately on each registrar as shown in this article to see if that make any difference: http://blog.schertz.name/2013/08/multiple-static-routes-in-lync/
I am having this exact issue with a single pool. I have a static route to “vc.domain.com” but calls never hit the route. It tries to route all calls to anyone@vc.domain.com to the edge and complains about the missing SRV record. What is strange is I have done interop with static routes before and this is the first time it hasn’t worked.
I have a ticket open with Microsoft, hopefully they can explain the behavior.
I have seen that issue before, randomly. Sometimes rebooting the Lync pool resolves it, other times rebooting the Polycom DMA/RMX resolves it. I have never found a root cause for Lync Server ignoring the static route table like this.
Hi Jeff. Always enjoy reading your excellent articles. We have a problem where countless vendors have not been able to provide an accurate answer.
In our organization, we are deploying Lync with split domain shared namespace, etc. Everything is fine and working between users who have a common SIP domain. But, our issue is that we have 3 SIP domains in the on-premise Lync infrastructure. When on-prem and online users who both have ‘domain1.com’ interact, all is great and working. users of domain1.com are the only users “moved to the cloud” as the plan.
The issue we have is when on-premise users who have SIP on-premise domain2.com and Lync Online users with domain1.com try to interact. We have “presence unknown” between them. I have torn apart of nicely setup infrastructure trying to figure out how to resolve it. No luck at all.
Did we receive bad info from our vendors that Lync Hybrid would work for our requirements? Are more than one SIP domain possible to use in this combination? Any ideas how to get it going?
what is also strange, is that I feel that all the issues are coming from the Lync Online side based on experiments, and the error massage (from both OP and Online users always saying source=”sipfed1A.online.lync.com”
This is the message error from the UCCP logs:
ms-diagnostics: 1017;reason=”Cannot route From and To domains in this combination”;cause=”Possible server configuration issue”;summary=”Domain type analysis indicates that the ms-split-domain-info header in the message is the wrong type”;external-domain=”domain2.com”;external-type=”domain-type-remote”;internal-domain=”domain1.com”;internal-type=”domain-type-none”;source=”sipfed1A.online.lync.com”
Server: RTC/6.0
I would really appreciate a comment of any kind. This challenge is driving me crazy.
Hi Fred. I am facing the same issue now, did you solve it?
I have same issue
Jeff,
Our internal SIP addresses are set to use SamAcctName (don’t ask), but when we attempt to federate we get an error message on the Edge server “The request URI domain is internally supported and cannot be routed to a federated partner”. The Federated partner is using the email address of the user in an attempt to locate them. Both the SamAcctName and the “outside name” are supported SIP domains in the internal setup, but Federation is still failing. Certs are good (nothing showing in the event logs anyway) and I can ping/telnet to the Federated partner’s Edge connection…
Out of ideas, hoping you have a flashlight to show me where I’m losing it.
As always, thank you for any pointers and/or assistance.
Hi Jeff,
We have a Federation set up in our environment its open federation all the setting are place as you mention above i.e we have two domain 1) abc.com and 2) xyz.biz the Federation and external Access setting is set on both the domain. now we have our own application is running on one domain i.e abc.com we are able to log in our application using the user created on xyz.biz the user is able receive IM and AV call. But on the Backend when we try to establish the userenpoint state from IDEL to ESTABLISH we are getting unhandled exception.
Exception
Unhandled Exception performing Action Establish: DeregisterReason=None
ResponseCode=504 ResponseText=Server time-out
DiagnosticInformation=ErrorCode=1017,Source=sip.abc.com,Reason=Cannot route From and To domains in this combination,internal-type=domain-type-remote,external-type=domain-type-remote,info=Possible server configuration issue,summary=The domain of the message that corresponds to remote peer (external) is not shared between local and remote deployments,internal-domain=xyz.biz,external-domain=xyz.biz
Microsoft.Rtc.Signaling.DiagnosticHeader
Microsoft.Rtc.Signaling.RegisterException:The endpoint was unable to register. See the ErrorCode for specific reason.
at Microsoft.Rtc.Signaling.SipAsyncResult`1.ThrowIfFailed()
at Microsoft.Rtc.Signaling.Helper.EndAsyncOperation[T](Object owner, IAsyncResult result)
at Microsoft.Rtc.Collaboration.LocalEndpoint.EndEstablish(IAsyncResult result)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Clarity.Connect.AgentFinder.Entities.AgentEndpoint.d__24.MoveNext()
Detected at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.Environment.get_StackTrace()
at Microsoft.Rtc.Signaling.FailureResponseException..ctor(String message, Exception innerException, SipResponseData responseData)
at Microsoft.Rtc.Signaling.RegistrationManager.SipRegisterAsyncResult.ProcessFailureResponse(SipResponse response)
at Microsoft.Rtc.Signaling.SipTransactionAsyncResult`1.Transaction_ResponseReceived(Object sender, ResponseReceivedEventArgs e)
at Microsoft.Rtc.Internal.Sip.SingleThreadedDispatcherQueue.DispatcherCallback(Object queue)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
Thanks,
Lalit