2016년 7월 6일 수요일

SIP 프로토토콜 흐름(RFC 3261)

SIP 프로토콜

opensips를 proxy로 PC에 설치하고, 안드로이드 SIP 어플 Linphone과 windows SIP어플 MicroSIP을 등록한 후 전화를 걸었을때 캡춰한 패킷을 중심으로 SIP 프로토콜 흐름을 설명했습니다. 대부분의 설명은 NExpert의 블로그글입니다.
2016년 7월 7일 신C

SIP Cilent, Proxy Server, SIP Server 전화통화 패킷캡춰

SIP User Agent Client, Alice: 192.168.1.26 (Linphone Android)
SIP Proxy: 192.168.1.17(opensips)
SIP User Agent Server, Bob: 192.168.1.114(MicroSIP)

82 INVITE : Client -> Proxy

RFC3261 Section 13.2.1
<Request-Line>
INVITE sip:bob@192.168.1.17 SIP/2.0
메세지의 첫 줄에는 Method와 메세지를 수신하는 최종 단말의 주소와 버전이 명기되므로 메세지가 생성된 목적을 확인할 수 있습니다.  
- INVITE : 요청한 메쏘드
- sip:bob@biloxi.com : Request URI
- SIP/2.0:  버전
Request-URI는일반적으로는 To 필드의 URI값을 이용하여 표시합니다
<message Header>
Via: SIP/2.0/UDP 192.168.1.26:5060;branch=z9hG4bK.REGZV7F7H;rport
Via 헤더는 요청에 대한 응답을 위한 경로를 나타냅니다.

branch는 시공간에서 유일한 값을 가지며, 트랜잭션 식별자입니다. 트랜잭션은 호 설정 또는 호 종료와 같은 단위작업을 의미하며 User Agent 간에 생성됩니다
84 INVITE요청에서 보면 프록시서버에서 UAS에 전달할때 UAC의 Via와 proxy의 Via 두개가 순서대로 들어간다.
이 branch 값은 서버로 부터 OK를 받을 때까지 유지된다. Bye의 branch도 OK를 받을때까지 유지된다.


rport: 클라이언트가 서버에게 요청한 주소와 포트로 응답해주는 것을 요청(rfc3581)
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: sip:bob@192.168.1.17
SIP 메세지의 출발지와 목적지를 나타내지만, 실제 메세지의 라우팅에 사용되지 않으며 Display Name의 의미를 가집니다.


이 줄은 앨리스가 밥에게 세션 설립을 요청하는 다이얼로그라는 의미입니다.


From과 To 헤더는 현재 세션의 진행방향을 의미하는 것으로 현재 메세지의 발신자와 수신자를 의미하는 것이 아닙니다. 따라서 SIP INVITE 메세지의 응답인 200 OK에서 From 과 To 헤더의 내용이 바뀌지 않습니다. From과 To의 값이 엉뚱하게 적혀있어도 SIP 프로토콜이 진행되는 데는 문제가 없습니다만, 요즘에는 SIP 보안이 강화가 되면서 From 과 To 헤더가 잘못 명기되면 호가 진행되지 않기도 합니다.
CSeq: 20 INVITE
Commnad Sequence또는 Sequence Number는 정수와 메쏘드 이름으로 나타냅니다. 새로운 요청을 생성할 때마다 1씩 증가시킵니다. 이 요청에 대한 응답인200 OK에서도 같은 값을 확인할 수 있습니다.


하나의 요청과 응답은 같은 CSeq값을 가집니다.  
Call-ID: ub5yOdNFB6
세션에 대한 global unique identifier로 사용하며, 호스트 네임 또는 IP address와 시간을 조합하여 생성됩니다. To/ From/ Call-ID가 결합으로 엘리스와 밥간의 Pee-to-peer SIP 관계를 정의합니다.


Call-ID가 같은면 하나의 다이얼로그로 인식하므로 세션의 설립과 종료사이의 모든 SIP 메세지는 동일한 Call-ID를 가집니다.  SIP 호 분석 시에 다수의 호가 혼재되어 있어도 Call-ID를 기준으로 개별 호에 대한 분석이 가능합니다. 다이얼로그는 다수의 트랜잭션으로 이루질 수 있으므로 트랜잭션의 식별은 Via헤더의 branch 값으로 추적하고, 다이얼로그의 식별은 Call-ID와 From 및 To의 Tag로 추적합니다.
Max-Forwards: 70
시그널링 경로 상에 SIP 서버의 최대 홉 수를 나타냅니다. IP네트워크의 TTL (Time to Live)과 같습니다
Supported: replaces, outbound
지원하는 new option(extention)을 나열합니다. 엘리스는 replaces, outbound 가 지원됩니다.
이런 option tag가 사용되는 필드:Require (Section 20.32), Proxy-Require (Section 20.29), Supported (Section 20.37), Unsupported (Section 20.40).
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE
지원 가능한 메소드를 나열합니다. 이 필드가 없을 경우 아무것도 지원하지 않는다고 해석하면 안됩니다. ‘지원 가능한 메소드가 뭔지 모르는 구나’로 해석해야 합니다.(Section 20.5)
Content-Type: application/sdp
메세지 바디가 있을 경우 메세지 바디에 대한 설명입니다.applicaiton/sdp는 SIP 메세지 바디가 SDP 메세지로 구성되었다는 의미입니다.
Content-Length: 483
메세지 바디의 크기를 옥텟 (바이트)로 표시합니다. 메세지 바디가 483 바이트로 구성되었다는 의미입니다.
Contact: <sip:6983@192.168.1.26>;+sip.instance="<urn:uuid:b1a8c819-e39d-47f4-8d15-18cbefede1f1>"
SIP URI 포맷으로 되어 있으며, 요청을 보낸 사용자에 대한 직접적인 경로를 나타냅니다.
일반적으로 FQDN (Fully qualified domain name)나 IP주소를 선호합니다.  Via 헤더 필드가 요청에 대한 응답 경로를 나타내고, Contact 헤더 필드는 미래의 요청을 보낼 경로를 말합니다.


예를 들어 proxy에서 UAS로 요청을 전달할 경우 Contact는 USC의 주소가 들어갑니다.
Contact URI: sip:6983@192.168.1.26, Contact parameter: +sip.instance=.....
User-Agent: LinphoneAndroid/3.1.1 (belle-sip/1.4.2)
요청한 UAC의 정보가 들어갑니다. alice는 Linephone Android 를 이용하고 있군요.(Section 20.41)
<messae Body>
v=0
: SDP프로토콜 버젼(RFC 4566), 현재까지는 Version 0 이 전부다.
o=6983 3953 1190 IN IP4 192.168.1.26
:소유자/작성자 및 세션 식별
형식 o=<username><sess-id><sess-version><nettype><addrtype><unicast-address>
<username>: 로그인 이름, 공백이 들어가면 안됨.
<sess-id>: 세션 아이디, 전화기에서 랜덤하게 생성된다
<session-version>: 세션의 버젼넘버, 전화기에서 랜덤하게 생성된다.
<nettype>: 네트워크 타입, 예)IN-internet, <addrtype>: 주소체계 예) IP4, IP6
<unicast-address> 세션을 생성한 단말기의 주소, IP 또는 FQDN(fully qualified domain name)
s=Talk
:세션 이름
c=IN IP4 192.168.1.26
: 연결정보
형식: c=<nettype> <addrtype> <connection-address>
<nettype>: 네트워크 타입, 예)IN-internet,
<addrtype>: 주소체계 예) IP4, IP6
<connection-address>: 멀티캐스트는 TTL을 포함한  IP 주소, 예) 224.2.36.42/127
b=AS:380
: 대역폭 정보
형식 b=<bwtype>:<bandwidth>
<bwtype>: Bandwith 타입은 CT(conference total), AS(application specific), TIAS(Transport Independent Application Specific)로 설정할 수 있다.  
TIAS: Transport Layer의 오버헤드를 고려하지 않은 대역폭으로 RTP만의 대역폭.
CT:컨퍼런스에서 사용될 최대 통합대역,
AS: 어플리케이션의 최대 사용 대역, TCP / UDP와 깉은 Transport Layer의 오버헤드를 고려한 대역폭으로 RTP/UDP/IP 의 대역폭
<bandwith>: kilobits per secnod 단위,
t=0 0
:세션이 활성화되는 시간
형식 t=<start-time>:<value>
세션의 시작, 마침 시간을 정한다. 만약 세션이 불규칙적으로 활성화되면, 여러개의 시간이 사용될 수 있다.
수화기를 들면 시작되므로 시작시간은 정해지지 않으므로 session start time은 0, 수화기를 놓을때 까지 통화가 되므로 session stop time도 0이다.
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics
: 미디어 속성
형식 a=<attribute>:<value>
속성은 세션 레벨 이거나 미디어 레벨 또는 둘다 해당할 수 있다. 세션레벨 속성은 컨퍼런스에 적용되는 추가적인 정보를 알리기 위해 사용된다. 미디어 레벨 속성은 미디어 스트림 정보처럼 미디어관련된 정보를 기술한다.
m=audio 7076 RTP/AVP 96 97 98 99 0 8 101 100 102
: 미디어 이름 및 전송 주소
형식: m=<media> <port>/<number of ports> <proto> <fmt>
<media>:  video, text 처럼 미디어 타입을 기술한다.
< port>: 미디어 스트림이 전송될 포트, 여러 포트를 기술할 수도 있다.
<proto>: 스트리밍을 위한 전송프로토콜, 예) RTP
<fmt>: 전송될 미디어 포맷, 예) PCMU, GSM 등.
a=rtpmap:96 opus/48000/2:
a=fmtp:96 useinbandfec=1:
a=rtpmap:97 SILK/16000:
a=rtpmap:98 speex/16000:
a=fmtp:98 vbr=on:
a=rtpmap:99 speex/8000:
a=fmtp:99 vbr=on:
a=rtpmap:101 telephone-event/48000:
a=rtpmap:100 telephone-event/16000:
a=rtpmap:102 telephone-event/8000:
:미디어 속성
사용자가 설정한 우선순위에 따라 코덱이 나열된다.

83 Giving a try : Proxy -> Client

RFC3261 Section 21.1.1
<Status-Line>
SIP/2.0 100 Giving a try
<Message Header>
Via: SIP/2.0/UDP 192.168.1.26:5060;received=192.168.1.26;branch=z9hG4bK.REGZV7F7H;rport=5060
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: sip:bob@192.168.1.17
CSeq: 20 INVITE
Call-ID: ub5yOdNFB6
Server: OpenSIPS (2.2.0 (x86_64/linux))
Content-Length: 0


84 INVITE : Proxy -> Server

RFC3261 Section 13.2.1
<Request-Line>
INVITE sip:bob@192.168.1.114:55903;ob SIP/2.0
<Message Header>
Record-Route: <sip:192.168.1.17;lr>
옵션 SIP 헤더로 SIP Message를 확인하려는 모든 SIP Proxy에 의해 삽입됩니다. SIP Proxy를 통해 경유되는 다이얼로그 (같은 Call-ID)에 대한 요청과 응답에 사용됩니다.  여러 대의 SIP Proxy를 경유해야 하는 경우에는 ","를 이용하여 계속 추가합니다.
예) Record-Route: server10.biloxi.com, bigbox3.atlanta.com
Via: SIP/2.0/UDP 192.168.1.17:5060;branch=z9hG4bK2891.db03d001.0
Via: SIP/2.0/UDP 192.168.1.26:5060;received=192.168.1.26;branch=z9hG4bK.REGZV7F7H;rport=5060
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: sip:bob@192.168.1.17
CSeq: 20 INVITE
Call-ID: ub5yOdNFB6
Max-Forwards: 69
Supported: replaces, outbound
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE
Content-Type: application/sdp
Content-Length: 483
Contact: <sip:6983@192.168.1.26>;+sip.instance="<urn:uuid:b1a8c819-e39d-47f4-8d15-18cbefede1f1>"
User-Agent: LinphoneAndroid/3.1.1 (belle-sip/1.4.2)
<Message Body>
v=0
o=6983 3953 1190 IN IP4 192.168.1.26
s=Talk
c=IN IP4 192.168.1.26
b=AS:380
t=0 0
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics
m=audio 7076 RTP/AVP 96 97 98 99 0 8 101 100 102
a=rtpmap:96 opus/48000/2
a=fmtp:96 useinbandfec=1
a=rtpmap:97 SILK/16000
a=rtpmap:98 speex/16000
a=fmtp:98 vbr=on
a=rtpmap:99 speex/8000
a=fmtp:99 vbr=on
a=rtpmap:101 telephone-event/48000
a=rtpmap:100 telephone-event/16000
a=rtpmap:102 telephone-event/8000


85 Trying : Server -> Proxy

RFC3261 Section 21.1.1
<Status-Line>
SIP/2.0 100 Trying
<Message Header>
Via: SIP/2.0/UDP 192.168.1.17:5060;received=192.168.1.17;branch=z9hG4bK2891.db03d001.0
Via: SIP/2.0/UDP 192.168.1.26:5060;rport=5060;received=192.168.1.26;branch=z9hG4bK.REGZV7F7H
Record-Route: <sip:192.168.1.17;lr>
Call-ID: ub5yOdNFB6
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: <sip:bob@192.168.1.17>
CSeq: 20 INVITE
Content-Length:  0


86 Ringing : Server -> Proxy

RFC3261 Section 21.1.2
<Status-Line>
SIP/2.0 180 Ringing
<Message Header>
Via: SIP/2.0/UDP 192.168.1.17:5060;received=192.168.1.17;branch=z9hG4bK2891.db03d001.0
Via: SIP/2.0/UDP 192.168.1.26:5060;rport=5060;received=192.168.1.26;branch=z9hG4bK.REGZV7F7H
Record-Route: <sip:192.168.1.17;lr>
Call-ID: ub5yOdNFB6
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
CSeq: 20 INVITE
Contact: "bob" <sip:bob@192.168.1.114:55903;ob>
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length:  0


87 Ringing : Proxy -> Client

RFC3261 Section 21.1.2
<Status-Line>
SIP/2.0 180 Ringing
<Message Header>
Via: SIP/2.0/UDP 192.168.1.26:5060;rport=5060;received=192.168.1.26;branch=z9hG4bK.REGZV7F7H
Record-Route: <sip:192.168.1.17;lr>
Call-ID: ub5yOdNFB6
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
CSeq: 20 INVITE
Contact: "bob" <sip:bob@192.168.1.114:55903;ob>
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length:  0


전화를 받으면(수화기를 들면) OK method가 전송된다.

113 OK : Server -> Proxy

RFC3261 Section 21.2.1
<Status-Line>
SIP/2.0 200 OK
<Message Header>
Via: SIP/2.0/UDP 192.168.1.17:5060;received=192.168.1.17;branch=z9hG4bK2891.db03d001.0
Via: SIP/2.0/UDP 192.168.1.26:5060;rport=5060;received=192.168.1.26;branch=z9hG4bK.REGZV7F7H
Record-Route: <sip:192.168.1.17;lr>
Call-ID: ub5yOdNFB6
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
CSeq: 20 INVITE
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Contact: "bob" <sip:bob@192.168.1.114:55903;ob>
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:   381
<Message Body>
v=0
o=- 3676737565 3676737566 IN IP4 192.168.1.114
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4006 RTP/AVP 96 102
c=IN IP4 192.168.1.114
b=TIAS:64000
a=rtcp:4007 IN IP4 192.168.1.114
a=sendrecv
a=rtpmap:96 opus/48000/2
a=fmtp:96 maxplaybackrate=16000;sprop-maxcapturerate=16000;maxaveragebitrate=16000;useinbandfec=1
a=rtpmap:102 telephone-event/8000
a=fmtp:102 0-16


114 OK : Proxy -> Client

RFC3261 Section 21.2.1
<Status-Line>
SIP/2.0 200 OK
<Message Header>
Via: SIP/2.0/UDP 192.168.1.26:5060;rport=5060;received=192.168.1.26;branch=z9hG4bK.REGZV7F7H
Record-Route: <sip:192.168.1.17;lr>
Call-ID: ub5yOdNFB6
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
CSeq: 20 INVITE
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Contact: "bob" <sip:bob@192.168.1.114:55903;ob>
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:   381
<Message Body>
v=0
o=- 3676737565 3676737566 IN IP4 192.168.1.114
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4006 RTP/AVP 96 102
c=IN IP4 192.168.1.114
b=TIAS:64000
a=rtcp:4007 IN IP4 192.168.1.114
a=sendrecv
a=rtpmap:96 opus/48000/2
a=fmtp:96 maxplaybackrate=16000;sprop-maxcapturerate=16000;maxaveragebitrate=16000;useinbandfec=1
a=rtpmap:102 telephone-event/8000
a=fmtp:102 0-16


119 ACK : Client -> Proxy

RFC3261 Section 17.1.1.3
<Request-Line>
ACK sip:bob@192.168.1.114:55903;ob SIP/2.0
<Message Header>
Via: SIP/2.0/UDP 192.168.1.26:5060;rport;branch=z9hG4bK.ckxiSqJN-
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
CSeq: 20 ACK
Call-ID: ub5yOdNFB6
Max-Forwards: 70
Route: <sip:192.168.1.17;lr>
User-Agent: LinphoneAndroid/3.1.1 (belle-sip/1.4.2)


120 ACK : Proxy -> Server

RFC3261 Section 17.1.1.3
<Request-Line>
ACK sip:bob@192.168.1.114:55903;ob SIP/2.0
<Message Heaer>
Via: SIP/2.0/UDP 192.168.1.17:5060;branch=z9hG4bK2891.db03d001.2
Via: SIP/2.0/UDP 192.168.1.26:5060;received=192.168.1.26;rport=5060;branch=z9hG4bK.ckxiSqJN-
From: <sip:6983@192.168.1.17>;tag=JtDxT530o
To: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
CSeq: 20 ACK
Call-ID: ub5yOdNFB6
Max-Forwards: 69
User-Agent: LinphoneAndroid/3.1.1 (belle-sip/1.4.2)


음성전송을 위한 RTP 세션이 시작되고, BYE method가 올때까지 지속된다.

485 BYE : Server -> Proxy

RFC3261 15.1.1
<Requrest-Line>
BYE sip:6983@192.168.1.26 SIP/2.0
<Message Header>
Via: SIP/2.0/UDP 192.168.1.114:55903;rport;branch=z9hG4bKPjdbdc963de20c4d52b471a2f18762a24f
Max-Forwards: 70
From: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
To: <sip:6983@192.168.1.17>;tag=JtDxT530o
Call-ID: ub5yOdNFB6
CSeq: 2505 BYE
Route: <sip:192.168.1.17;lr>
User-Agent: MicroSIP/3.12.1
Content-Length:  0


486 BYE : Proxy -> Client

RFC3261 15.1.1
<Request-Line>
BYE sip:6983@192.168.1.26 SIP/2.0
<Message Header>
Via: SIP/2.0/UDP 192.168.1.17:5060;branch=z9hG4bKfada.93f51355.0
Via: SIP/2.0/UDP 192.168.1.114:55903;received=192.168.1.114;rport=55903;branch=z9hG4bKPjdbdc963de20c4d52b471a2f18762a24f
Max-Forwards: 69
From: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
To: <sip:6983@192.168.1.17>;tag=JtDxT530o
Call-ID: ub5yOdNFB6
CSeq: 2505 BYE
User-Agent: MicroSIP/3.12.1
Content-Length:  0


493 OK : Client -> Proxy

RFC3261 Section 21.2.1
<Status-Line>
SIP/2.0 200 Ok
<Message Header>
Via: SIP/2.0/UDP 192.168.1.17:5060;branch=z9hG4bKfada.93f51355.0
Via: SIP/2.0/UDP 192.168.1.114:55903;received=192.168.1.114;rport=55903;branch=z9hG4bKPjdbdc963de20c4d52b471a2f18762a24f
From: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
To: <sip:6983@192.168.1.17>;tag=JtDxT530o
Call-ID: ub5yOdNFB6
CSeq: 2505 BYE
User-Agent: LinphoneAndroid/3.1.1 (belle-sip/1.4.2)
Supported: replaces, outbound

494 OK : Proxy -> Server

RFC3261 Section 21.2.1
<Status-Line>
SIP/2.0 200 Ok
<Message Header>
Via: SIP/2.0/UDP 192.168.1.114:55903;received=192.168.1.114;rport=55903;branch=z9hG4bKPjdbdc963de20c4d52b471a2f18762a24f
From: <sip:bob@192.168.1.17>;tag=a42de3df101a4d4d92092d28a588aa10
To: <sip:6983@192.168.1.17>;tag=JtDxT530o
Call-ID: ub5yOdNFB6
CSeq: 2505 BYE
User-Agent: LinphoneAndroid/3.1.1 (belle-sip/1.4.2)
Supported: replaces, outbound



댓글 없음:

댓글 쓰기