สำหรับบางท่านที่นำ Asterisk ไปใช้งานแบบให้บริการลูกค้าหรือโทรกันภายในสาขา ส่วนใหญ่มักจะไม่ได้สนใจออปชั่น canreinvite ในไฟล์ sip.conf กันสักเท่าไหร่ ออปชั่นนี้ช่วยให้เราลด Bandwidth ที่ Asterisk Server จำเป็นต้องใช้ไปได้มากโขเลยนะครับ ผมก็เคยอ่านๆอยู่แต่ก็ยังไม่เคยได้ลองเอามาใช้งานจริงๆสักที วันนี้มีโอกาสได้ใช้งาน แต่ลองตั้งนานกว่าจะเวอร์ค ถ้าอ่านบทความนี้แล้วทำตาม ไม่เกิน 1 นาทีก็ใช้งานได้แล้วครับ
ขออนุญาตเอ่ยถึงเบสิค VoIP พอเป็นพิธีนะครับ VoIP ไม่ว่าจะเป็นแบบโปรโตคอลไหนก็แล้วแต่ เช่น SIP, H.323, MGCP, IAX2 มันจะประกอบด้วย 2 ส่วนคือ Signaling และก็ Media ซึ่ง Signaling นี่แหล่ะครับที่บ่งบอกว่าเป็น SIP หรือ H.323 หรือ IAX2 ส่วน Media คือสัญญาณเสียงหรือบ้างก็เรียกว่า RTP เป็นส่วนที่กิน Bandwidth มากที่สุด ถ้าเราไม่เอา RTP มาผ่าน Asterisk เราก็จะลดการใช้ Bandwidth ไปได้มาก ยิ่งถ้าเป็น Bandwidth ต่างประเทศด้วยหล่ะก็ลดเงินค่าเช่า Bandwidth ไปได้มากมายเลยทีเดียว เป็นเทคนิคที่ VoIP Provider ใช้กันอยู่โดยทั่วไปครับ
ลองใช้ดูครับ Bandwidth จะลดลงไปได้มากกว่า 95% เลยทีเดียว
สมมติว่า Asterisk อยู่ตรงกลาง ต้นทางเป็น Client A ปลายทางเป็น Client B เมื่อ A จะโทรไปหา B มันจะส่ง Signalig มาที่ Asterisk ก่อน จากนั้น Asterisk จะส่ง Signaling ไปที่ B สมมติว่า B รับสายแล้ว Asterisk จะส่งข้อมูลไปบอก A ว่า ไอพีที่จะแฮนเดิ้ลเสียง RTP เป็นไอพีอะไร ปกติที่่เราทำๆอยู่นะครับ จะเป็น IP ของ Asterisk เอง ซึ่ง Asterisk จะต้องรองรับ Bandwidth มากโดยไม่จำเป็น เทคนิค canreinvite จะทำให้ตรง RTP เป็นไอพีของ B แทน และ A จะคุยกับ B ตรงๆไม่ผ่าน Asterisk
มาดู SIP Message กันก่อนครับ ผมแค๊ปเจอร์ด้วยโปรแกรม ngrep
U 192.168.1.215:56259 -> 10.10.255.19:5060
INVITE sip:100@10.10.255.19:5060 SIP/2.0..Via: SIP/2.0/UDP 192.168.1.215:5060..From: <sip:192.168.1.215>;tag=3DE91
CCC-1B1..To: <sip:100@10.10.255.19>..Date: Wed, 05 May 2010 08:36:34 GMT..Call-ID: 25D2EFE8-575811DF-A9C1A46F-B6B
4FB2F@192.168.1.215..Supported: timer,100rel..Min-SE: 1800..Cisco-Guid: 634500863-1465389535-2847843439-3065314095..User-Agent:
Cisco-SIPGateway/IOS-12.x..Allow: INVITE, OPTIONS, BYE, CANCEL, ACK, PRACK, COMET, REFER, SUBSCRIBE, NOTIFY, INFO..CSeq: 101 I
NVITE..Max-Forwards: 15..Remote-Party-ID: <sip:192.168.1.215>;party=calling;screen=no;privacy=off..Timestamp: 1273048594..Contac
t: <sip:192.168.1.215:5060>..Expires: 180..Allow-Events: telephone-event..Content-Type: application/sdp..Content-Length: 351....
v=0..o=CiscoSystemsSIP-GW-UserAgent 7657 2682 IN IP4 192.168.1.215..s=SIP Call..c=IN IP4 192.168.1.215..t=0 0..m=audio 16500 RTP/
AVP 18 121 101 19..c=IN IP4 192.168.1.215..a=rtpmap:18 G729/8000..a=fmtp:18 annexb=no..a=rtpmap:121 frf-dialed-digit/8000..a=fmt
p:121 0-15..a=rtpmap:101 telephone-event/8000..a=fmtp:101 0-16..a=rtpmap:19 CN/8000..a=ptime:20..
ไอพี 192.168.1.215 ส่ง Invite มาที่ Asterisk ไอพี 10.10.255.19 ว่าขอโทรไปยังเบอร์ Extension 100 ใน Invite ก็จะประกอบไปด้วยหลายๆเฮดเดอร์ หนึ่งในนั้นก็คือ c=IN IP4 192.168.1.215 m=audio 16500 บอกว่ามันจะใช้ไอพี 192.168.1.215 เป็น Media (RTP) ใช้พอร์ต 16500 และใช้ Codec G.729
U 10.10.255.19:5060 -> 192.168.1.215:5060
SIP/2.0 100 Trying..Via: SIP/2.0/UDP 192.168.1.215:5060..From: <sip:192.168.1.215>;tag=3DE91CCC-1B1..To: <sip:100@20
2.170.124.19>;tag=329b488d069e800f..Server: V4S..CSeq: 101 INVITE..Call-ID: 25D2EFE8-575811DF-A9C1A46F-B6B4FB2F@192
.168.1.215..Contact: <sip:100@10.10.255.19:5060>..Max-Forwards: 70..Content-Length: 0....
ตอบกลับไปว่ารอสักครู่กำลังเชื่อมต่อปลายทางให้
U 10.10.255.19:5060 -> 192.168.1.215:5060
SIP/2.0 183 Session Progress..Via: SIP/2.0/UDP 192.168.1.215:5060..From: <sip:192.168.1.215>;tag=3DE91CCC-1B1..To: <sip:18006681
9109497@10.10.255.19>;tag=329b488d069e800f..Server: VOS2009 V2.1.1.5..CSeq: 101 INVITE..Call-ID: 25D2EFE8-575811DF-A9C1A46F-B
6B4FB2F@192.168.1.215..Contact: <sip:100@10.10.255.19:5060>..Max-Forwards: 70..Content-Length: 167..Content-Type:
application/sdp....v=0..o=- 7657 2682 IN IP4 192.168.4.219..s=VOS2009..c=IN IP4 192.168.4.219..t=0 0..m=audio 11492 RTP/AVP 1
8..a=rtpmap:18 G729/8000..a=fmtp:18 annexb=no..a=sendrecv..
ตอบกลับไปว่ากำลังรอให้ปลายทางรับสาย สังเกตุที่ c=IN IP4 192.168.4.219 นะครับ มันเป็น IP ของปลายทาง ไม่ใช่ IP ของ SIP Server (ถ้าเราไม่ใช้เทคนิค canreinvite ไอพีตรงนี้จะเป็นของ SIP Server เอง ซึ่งจะส่งผลให้เฟสต่อมาคือรับส่ง RTP ต้นทางจะส่ง RTP มาที่ SIP Server) พร้อมระบุพอร์ต RTP เป็น 11492 และโคเด็ค G.729
U 10.10.255.19:5060 -> 192.168.1.215:5060
SIP/2.0 200 OK..Via: SIP/2.0/UDP 192.168.1.215:5060..From: <sip:192.168.1.215>;tag=3DE91CCC-1B1..To: <sip:100@202.17
0.124.19>;tag=329b488d069e800f..Server: V4S..CSeq: 101 INVITE..Call-ID: 25D2EFE8-575811DF-A9C1A46F-B6B4FB2F@192.168.1.215..
Contact: <sip:100@10.10.255.19:5060>..Max-Forwards: 70..Require: timer..Session-Expires: 1800;refresher=u
ac..Supported: timer..Allow: INVITE, ACK, CANCEL, BYE, OPTIONS, INFO, UPDATE..Content-Length: 167..Content-Type: application/sd
p....v=0..o=- 7657 2682 IN IP4 192.168.4.219..s=V4S..c=IN IP4 192.168.4.219..t=0 0..m=audio 11492 RTP/AVP 18..a=rtpmap:18
G729/8000..a=fmtp:18 annexb=no..a=sendrecv..
ปลายทางเบอร์ Extension 100 รับสายแล้ว ซึ่งจากข้อมูลไอพีแอดเดรสใน c=IN IP4 192.168.4.219 และ RTP Port ใน m=audio 11492 จะทำให้ต้นทางคือ 192.168.1.215 รับส่ง RTP กับปลายทาง 192.168.4.219 โดยตรง โดยไม่ผ่าน SIP Server
เฉพาะ RTP เท่านั้นนะครับที่ไม่ผ่าน SIP Server ทำให้ลดการใช้งาน Bandwidth ลงไปได้มากเกินกว่า 95% ซะอีก ส่วน Signaling อย่างอื่นก็ยังผ่าน SIP Server อยู่เหมือนเดิม แต่กิน Bandwidth น้อยมาก
ผมมีกราฟ Bandwidth เปรียบเทียบให้ดูด้วยครับ
ไว้ผมจะเขียนรูปมาให้ดูนะครับว่ามัน Flow ยังไง
ต่อไปมาดูวิธีการเปิดออปชั่น canreinvite ครับ
ไฟล์ sip.conf
[global]
;canreinvite=yes
directrtpsetup=yes
[trunk_1]
canreinvite=yes
[trunk_2]
canreinvite=yes
[sip_client_1]
canreinvite=yes
[sip_client_2]
canreinvite=no
แต่สำหรับคอนฟิกของ SIP Client ที่ต่ออยู่หลัง ADSL Router (NAT Device) ให้เซ็ต canreinvite=no นะครับ
ไฟล์ extensions.conf
เวลาใช้คำสั่ง Dial ห้ามมีออปชั่นต่อไปนี้นะครับ t, T, h, H, w, W หรือ "L" งั้น canreinvite จะไม่เวอร์ค
แต่เทคนิคนี้มีข้อแม้นะครับ ถ้าเอาไปใช้งานกับ Asterisk ที่มี SIP Client อยู่หลัง ADSL Router (NAT) หล่ะก็ อาจจะไม่เวอร์คก็ได้ เช่นโทรแล้วไม่ได้ยินเสียง ยังไงก็ปรับแต่งค่า canreinvite เอาหล่ะกัน ซึ่งมีให้เลือกใช้คือ yes, no, nonat, update