User location
Let's step out of the SIP layers and see what we have so far: using the layers, we can now create and receive SIP transactions.
One basic requirement in SIP is for phone devices to be able to register their location with a registrar. Using this registration information, we can send a request to a server and this request would reach the intended recipient. Let's go back to the previous example:
REGISTER sip:arstechnica.com SIP/2.0
Via: SIP/2.0/UDP home.mynetwork.org;branch=z9hG4bKmq0Tgb
To: sip:me@arstechnica.com
From: sip:me@arstechnica.com;tag=m25caI4
Call-ID: n35nzlsdjfb3@home.mynetwork.org
CSeq: 153 REGISTER
Contact: sip:me@home.mynetwork.org
Max-Forwards: 70
We already covered the first two lines, so let's now look at the rest.
- The Contact header tells the registrar the actual address of the device; many times you'll see an IP rather than a domain name in this field.
- The To header tells the registrar the address of record (usually referred as the AOR). AOR is the public SIP address, the same as my email address.
- The From header usually has the same value as the To. (It would be different in case someone is registering on behalf of someone else, but this case is rare.)
-
Call-ID is an identifier that groups together a series of messages. Two different registrations should have different Call-ID values, but re-registrations should have the same Call-ID values. To differentiate the re-registrations, the client would increment the CSeq value.
- We'll leave the Max-Forwards explanation for the last section.
The client may also add an expiration value to the registration, either by adding a new Expires header or by adding an Expires parameter to the contact header. This is a recommended value to the server, because the server is the party that chooses the expiration time and sends it in the successful response. The expiration time may not be higher than the client-requested value, and if the value is below the minimum acceptable value then the registrar should reject the request.
Registering multiple user devices
A user is not bound to register with only one device, since it's possible that the user owns several SIP-capable devices and wants to be able to use the same SIP address simultaneously. A simple example involves two phones, one a desk phone and the other a cell phone. When someone calls the public SIP address, both phones would ring. To accomplish this, both devices register with the same AOR but different contact values. The registrar receiving these registrations maintains both associations. Requests arriving to the user AOR would fork to both devices. In some cases, it may make sense that both devices would create a session, but most of the time, this would be a call and thus the first device that answers would establish the call. Anyone who has a cell phone and a car phone with the same phone number is quite familiar with this scenario.
The fact that SIP lets several devices register originally worked out well, but then more complex scenarios started to come up. Suppose a user with two devices is in a conversation, and the person on the other end transfers the call to a third party. In SIP, it would mean the third party would send a request to the first user, but if it were to use the AOR, the request would fork to both devices. A device that is not active in the call would not be able to transfer a non-existent call. In this case, you might suggest using the device IP value, but many times, this will be a non-routable IP address, and the only way to reach it is via a server that has access to this private network.
For such scenarios, an extension called GRUU (Globally Routable User Agent URI) was introduced, defined in RFC 5627. When a user registers with a device that supports this extension, a header parameter named "+sip.instance" with a unique identifier is added to the contact header. The registrar creates two GRUUs for that instance: a public GRUU with the identifiable AOR, and a temporary GRUU to be used in case the user wants to make an anonymous call. Both these GRUUs are SIP addresses with a "gr" parameter. Now when there's a call with one of the devices, the contact address would have the GRUU SIP address. A transfer request would use this value, and because the server has a mapping between this GRUU and the actual device instance, the request reaches a single device participating in the call rather than the other devices.
Locating servers
A SIP client that wishes to register to sip:arstechnica.com needs to resolve this address. SIP uses DNS to do that, but simply resolving the address to an IP is not enough. Therefore, SIP uses DNS to discover everything it needs to send the request. All the procedures I describe in this section are detailed in RFC 3263.
First, the client needs to discover the preferred transport type. For example, a client that supports UDP, TCP and SCTP performs a NAPTR query (defined in RFC 3403) for arstechnica.com. A response for such query may be:
; order pref flags service regexp replacement
IN NAPTR 50 50 "s" "SIPS+D2T" "" _sips._tcp.arstechnica.com.
IN NAPTR 90 50 "s" "SIP+D2T" "" _sip._tcp.arstechnica.com.
IN NAPTR 80 50 "s" "SIP+D2S" "" _sip._sctp.arstechnica.com.
IN NAPTR 100 50 "s" "SIP+D2U" "" _sip._udp.arstechnica.com.
That means the server supports TLS, TCP, SCTP and UDP in this order. The service value determines the transport type. A client that does not support TLS will choose the second option, "SIP+D2T" which means "SIP over TCP." To use TCP, the client now needs to resolve _sip._tcp.arstechnica.com.
We have the transport type, but now the port is unknown. It is true that the default port is 5060, but this port will only be used if we cannot resolve a different port. To resolve the port, the client performs an SRV query (this type is defined in RFC 2782) for _sip._tcp.arstechnica.com. A possible response to this query may be:
;; Priority Weight Port Target
IN SRV 0 1 5060 server1.arstechnica.com
IN SRV 0 2 5070 server2.arstechnica.com
Now it's finally time to resolve the IP address. The client tries to send the request to server1.arstechnica.com, port 5060 via TCP. To find the correct IP address, the client performs an A query on IPv4 or AAAA query on IPv6. If the transaction times out, then the client should not stop at this point. It should try to send a new request to server2.arstechnica.com, port 5070 and transport TCP. If this also fails, then the client stops because it’s the last SRV record. So, SRV records are not just for resolving the port, but are also useful for server redundancy and load balancing.
Naturally, this elaborate process of doing different DNS queries takes time, and will significantly increase latency if you want to send many SIP messages. Hence, the assumption is that the client caches these DNS results. This is a reasonable assumption, since HTTP clients also cache DNS to improve performance. There are other possibilities for overriding these queries. The first is to use a numeric IP address, but this is not recommended for obvious reasons. The other option is to specify the values in the SIP URI itself. One can specify its address as: sip:arstechnica.com:5060;transport=tcp. This is also not recommended, since changing the values requires changing the URI. Furthermore, the server redundancy supported by the SRV records would not be available.
Proxies
Now let's look at SIP proxies to see how the different pieces fall together. You rarely send signaling messages directly between phone devices. Usually, there's at least one, if not several, proxies along the signaling path, and these proxies are designed to be aware of transactions, not calls. (Such a design is more scalable.)
Proxies act as both UAC and UAS. An incoming request goes to the proxy UAS side, and the proxy then creates a new transaction as a UAC. Responses reach the UAC, and the proxy generates responses as a UAS. Therefore, for an incoming transaction and a corresponding outgoing transaction, the transaction layer maintains two state-machines, and it's the proxy's job to manage the interaction of these two transactions.
Some proxies work in conjunction with a registrar and have access to a shared database. It's such a proxy's job to retrieve a user's public AOR and to resolve its registered contact address. Other proxies simply route the messages. I should note at this point that this section focuses on stateful proxies. The standard also defines stateless proxies, so some of the text here would not apply to those server types.
The Via header, forking, loop prevention
When we went through the transport layer, I added a vague description of the top Via header. Now it's time to address this header in more detail.
A SIP message may contain more than a single Via header. When a proxy constructs a request for a new transaction, it takes the existing message and adds an additional Via header above the existing, topmost Via header. This Via header has a new "branch" parameter value, thus signifying that this is a new transaction and that its address is the proxy's UAC-side address. The UAS receiving this request would send the response based on the top Via header, thereby ensuring that the response goes back to the proxy. If the proxy sends back the response, it sends it without its own Via header, because the original transaction is a different one and has a different top Via header with a different "branch" value. Proxies use a similar mechanism with route and record-route headers, but this subject is covered in the next part of the article.
I mentioned previously that a single user can register with multiple devices. In order to send a request to multiple targets, the proxy forks a request. An incoming request may result in several outgoing requests to different targets, each containing a different branch value. Proxies will not forward every failed final response to the UAC because the first final response would cause the UAC to close the transaction. Therefore, the proxy collects the error responses, and if all the outgoing transactions fail, it chooses the most appropriate failed response. A successful response is sent back to the UAC immediately. This is why we saw that an ACK request is part of the transaction for a failed response. For INVITE transactions, the proxy sends out an ACK for failed responses and does not wait until the other responses arrive. On the other hand, the proxy cannot ACK a successful 2xx response to INVITE since this means a new call was created, but the caller is not aware of this yet.
To prevent loops, proxies use the Max-Forwards header. This is the last of the mandatory headers that I skipped in earlier sections. The initial request is sent out with a value, most commonly 70, and every proxy that forwards this request deducts 1 from the value in the request that it sends out. If the value of the Max-Forwards reaches 0 before it reaches the final destination, the UAS sends back a 483 (Too Many Hops) response. It should be noted that a possible amplification vulnerability was later discovered for forking proxies. This was addressed by RFC 5393, which changed some loop detection mechanisms and introduced a new header called Max-Breadth that reduces the number of possible forks a message goes through.
Finally, proxies send out a 100 (Trying) provisional response when they receive a request whose response takes more than 200 ms. This prevents the UAC from retransmitting the request, and it also prevents a time-out event. 100 is a response that is generated by the proxy. If we have more than one proxy, the proxy that receives the 100 message will not forward it. This is because it should have sent its own 100 message prior to receiving it.
An example using proxies
Let's look at an example to wrap up this discussion (non-essential details elided, including the SIP version in the first line of the request and some headers that will be discussed when we cover calls):
This message is sent from Ars Technica's network and reaches the arstechnica.com SIP proxy. The proxy sends out the message to the voxisoft.com SIP proxy and returns a 100 response. Voxisoft's proxy has two registrations and forks the request to two devices (while also sending out a 100 response). Notice that all new requests have a new Via header with a new branch parameter. Also, note that the second message is using TCP as a transport. This is a valid scenario, as we previously discussed, since both transactions have different state machine and one of them may discover a different transport when performing a NAPTR query.
At this point, one device might answer with, for example, 486 (Busy), but the proxy does not forward it because it has another forked message pending; so it just sends an ACK. The ACK has the same branch value since it's the same transaction. ACK is sent only for the INVITE case; if this were a different method then ACK wouldn't be used. The second device sends a 200 OK and this message is sent all the way back to the initiating client. The following illustration shows this process in action:
Finally, the client on the left side sends out an ACK for the 200 OK. This ACK is a new transaction and therefore has a new branch value. The proxies forward the request to the destination, again adding a Via header for each hop. This time ACK does not fork; we will see this mechanism in the next article.
Summary
In this article, we've covered the foundation layers of SIP, including its message structure, transport layer and transaction layer. We've also covered the way SIP registrars and proxies work based on these layers. The discussion so far should give you a good foundation for understanding this protocol. In the next part of this series of articles, we'll complete this discussion by going through the definitions of SIP calls and additional services.
分享到:
相关推荐
操作手册-voip语音服务器-Avaya 语音cm服务器和sip服务器日常配置备份手册 CM配置备份(SIP服务器一样) Strong IE界面等登陆CM服务器-active 172.16.2.163 --backup now 选者full-backup 将配置文件全备份,包括LIC...
SIP电话WebRTC 这是 SIP电话,可以轻松集成到您的Web应用程序中以进行音频和视频通话。 它使用生产的 如何使用克隆存储库"git clone https://github.com/alepolidori/janus-webrtc-phone.git" 运行"npm install" 在...
python3-sipsimple:用Python编写的SIP SIMPLE SDK
SIP: Understanding the Session Initiation Protocol, Fourth Edition 英文原版,第4版
2 Introduction to SIP 17 2.1 A Simple Session Establishment Example 17 2.2 SIP Call with Proxy Server 25 2.3 SIP Registration Example 31 2.4 SIP Presence and Instant Message Example 33 2.5 Message ...
sip3-parent:SIP3父POM
Go-Sip-UA 使用golang的client / b2bua的SIP UA库特征 传输UDP / TCP / TLS / WS / WSS。 简单的纯Go SIP客户端。 简单的纯Go B2BUA,支持RFC8599,Google FCM / Apple PushKit。 RTP中继(UDP <-> UDP,WebRTC /...
sip构建java源码很棒的语音 :red_heart: 支持我的应用 :red_heart: :red_heart: :red_heart: :smiling_face_with_halo: :smiling_face_with_heart-eyes: :sign_of_the_horns: :red_heart: :red_heart: 在使用 ...
SIP呼叫通知 基于 eXosip/osip 的基本 SIP 客户端,使用 libnotify 显示每个传入呼叫的小通知。 作者:Mario Kicherer ( ) 许可证: GPL v2 ( ) AVM FritzBox 等现代无线路由器还包括 DECT 基站和 VoIP 连接等...
该项目将标准PJSUA2绑定包装在后台服务中,并在应用程序的其余部分完全隐藏了SIP,从而能够以较高的抽象级别具有VoIP功能。 您可以使用静态方法与服务进行对话,并且您将收到广播意图作为响应。 要与服务对话,请...
安装的软件版本 操作手册-VoIP服务器-Avaya语音服务器系统安装配置文档全文共11页,当前为第1页。 继续安装 完成安装,S8700重 操作手册-VoIP服务器-Avaya语音服务器系统安装配置文档全文共11页,当前为第2页。IE...
它完全基于SIP,可用于所有呼叫,状态和IM功能。 可以从获得一般描述。 执照 版权所有:copyright:Belledonne Communications Linphone具有双重许可,并且可以选择: 根据,是免费的(开放源代码)。 在使用前,...
:high_voltage: | :check_mark_button:沟通对话:IRC客户端-https: :check_mark_button: 不和谐:功能丰富的VoIP客户端与无尽的有趣的发球- :high_voltage: | :check_mark_button: Microsoft Outlook:首选的电子...
sip3-twig-ce:SIP3 Twig(社区版)
With this practical, in-depth guide to the entire network infrastructure, you’ll learn how to deal with real Cisco networks, rather than the hypothetical situations presented on exams like the CCNA....
sip3-captain-ce:SIP3队长(社区版)
voip-elk-stack 在这里,您将找到基于Elasticsearch / Logstash / Kibana的VOIP分析平台的实现。 为什么 ? 我没有找到很多分析VOIP质量的开源解决方案。 实际上,唯一的一个就是我曾经使用过的 。 为什么不HOMER...
Routr - 使用Javascript构建的下一代SIP服务器,轻松部署多租户VoIP网络
VoIP服务器----Asterisk,从实现电话免费大餐、免费的VOIP服务、Asterisk的安装和配置等深入讲解
sip3-commons:SIP3 Commoms