struktur pesan protokol sip
TRANSCRIPT
LAMPIRAN A
Struktur Pesan Protokol SIP
Struktur pesan SIP secara umum terdiri dari empat bagian yang disusun
secara berurutan, yaitu Start-Line, Message Header, Empty Line, serta Body
(opsional). Pada akhir setiap bagian pesan tersebut akan disertakan karakter
carriage-return line-feed (CR-LF), sehingga bagian selanjutnya akan diletakkan
pada baris dibawahnya. Gambar A.1 menampilkan struktur umum dari pesan
protokol SIP.
A.1 Start-Line
Start-Line dari pesan SIP berbeda antara pesan request dan pesan
response.
A-1
Gambar A.1 Struktur pesan SIP
Universitas Sumatera Utara
A.1.1 Start-Line pesan Request
Start-Line dari pesan request disebut juga sebagai Request-Line dan terdiri
dari nama metoda (Method), alamat URI tujuan (Request-URI), serta versi
protokol SIP (Version) yang disusun secara berurutan. Diantara setiap bagian pada
Request-Line ini dipisahkan oleh satu karakter spasi tunggal (SP). Syntax dari
Request-Line ini ditampilkan pada Gambar A.1 (b).
Metoda dari sebuah pesan request mengandung fungsi/operasi yang
diminta untuk dijalankan pada server tujuan. Protokol SIP sendiri mengenal
sembilan jenis metoda, yaitu INVITE, ACK, OPTION, BYE, CANCEL,
REGISTER, SUBSCRIBE, REFER, dan NOTIFY. Tabel A.1 menampilkan
sembilan metoda ini beserta deskripsi fungsinya. Pada Tugas Akhir ini sendiri
hanya akan digunakan Method INVITE, ACK, BYE dan CANCEL.
Tabel A.1 SIP Request Method
Method Deskripsi
INVITE Mengundang untuk memulai sesi SIP
ACK Mengkonfirmasi bahwa pertukaran message berhasil
OPTION Meminta informasi mengenai kemampuan pemanggil
BYE Mengakhiri sesi yang telah terbentuk
CANCEL Membatalkan sesi yang menunggu
REGISTER Mendaftarkan informasi mengenai user agent pada sebuah registrar server
SUBSCRIBE Meminta pemutakhiran informasi
REFER Mengalihkan panggilan atau menghubungi sumber daya eksternal
NOTIFY Menyediakan informasi tentang perubahan status
A-2
Universitas Sumatera Utara
Alamat URI (Uniform Resource Identifier) tujuan mengindikasikan
pengguna atau layanan kemana pesan request ini ditujukan. Setiap pengguna akan
dialamati dengan sebuah penamaan URI khusus yang dinamakan SIP URI.
Format penamaan ini mirip dengan format penamaan yang digunakan pada
layanan email, terdiri dari user name pengguna serta alamat domain dimana
pengguna tersebut terdaftar dengan dipisahkan oleh sebuah karakter “@”. Di
depan user name pengguna kemudian ditambahkan prefix “sip:”, sehingga syntax
dari format penamaan ini menjadi seperti “sip:username@host”.
Version ditampilkan sebagai string “SIP/x .y”, dimana x dan y masing-
masing menunjukkan versi mayor dan minor dari protokol SIP yang digunakan.
Saat ini versi protokol SIP terakhir yang telah dikeluarkan oleh IETF adalah versi
2.0.
Berikut ini adalah contoh Request-Line dari sebuah pesan request dengan
metode INVITE yang ditujukan kepada bob yang terdaftar dalam domain
usu.ac.id menggunakan protokol SIP versi 2.0.
INVITE sip:[email protected] SIP/2.0
A.1.2 Start-Line pesan Response
Start-line dari pesan response disebut juga sebagai Response-Line dan
terdiri dari versi protokol yang digunakan (Version), Status Code dan Reason
Phrase. Sebagaimana Request-line, diantara setiap bagian pada Response-Line ini
dipisahkan oleh satu karakter spasi tunggal (SP). Syntax dari Respons-Line ini
ditampilkan pada Gambar A.1 (c).
A-3
Universitas Sumatera Utara
Status Code merupakan tiga digit integer yang mengindikasikan tingkatan
(status) dari fungsi/operasi yang diminta UAC melalui pesan request. Protokol
SIP membagi pesan response kedalam enam kelas yang ditunjukkan oleh bit
pertama dari Status Code. Sebagai contoh status code 100 hingga 199 termasuk
dalam kelas 1xx (provisional). Tabel A.2 menampilkan pembagian kelas pesan
response ini beserta deskripsinya.
Tabel A.2 Kelas-kelas pesan SIP Response
Status Code
Kelas Deskripsi
1xx Provisional Request telah diterima dan sedang diproses
2xx Success Request telah diterima, dimengerti, dan disetujui
3xx Redirection Diperlukan langkah berikutnya untuk menyelesaikan permintaan
4xx Client Failure Request mengandung syntax yang salah / tidak dapat dipenuhi server
5xx Server Failure Tidak dapat memenuhi permintaan diakibatkan kesalahan pada server
6xx Global Failure Request tidak dapat dipenuhi oleh server berikutnya
Reason Phrase merupakan deskripsi tekstual singkat dari Status Code
yang digunakan. Beberapa Reason Phrase dari Status Code yang umum ditemui
dan akan digunakan pada Tugas Akhir ini ditampilkan pada Tabel A.3.
Tabel A.3 Reason Phrase dari beberapa Status Code
Status Code Reason Phrase
100 Trying
180 Ringing
200 OK
408 Request timeout
480 Temporarily Unavailable
A-4
Universitas Sumatera Utara
Berikut ini adalah contoh Response-Line dari sebuah pesan response
dengan Status Code 200 menggunakan protokol SIP versi 2.0.
SIP/2.0 200 OK
A.2 Message Header
Message header mengandung informasi lengkap mengenai pesan SIP dan
disusun menggunakan syntax sebagaimana ditampilkan pada Gambar A.1 (d).
Bagian ini terdiri dari beberapa baris header field, dimana pada setiap header field
ini terdiri dari field name dan field value yang dipisahkan oleh sebuah karakter
titik-dua (colon). Bagian field name akan mengindikasikan jenis informasi yang
nilainya diberikan pada bagian field value. Tabel A.4 menampilkan daftar header
field name yang dikenal protokol SIP beserta deskripsi informasi yang akan
terkandung pada baris tersebut. Urutan setiap header field dalam message header
tidak harus mengikuti susunan tertentu.
Tabel A.4 Header Field yang digunakan pada protokol SIP
Header Field Name Deskripsi Informasi
Call-ID Mengandung identitas unik untuk panggilan yang dilakukan
Contact Menunjukkan jalur langsung untuk menghubungi pemanggil
Content-Length Mengandung panjang bagian body dari pesan SIP (dalam byte)
Content-Type Menunjukkan tipe pesan yang terkandung pada bagian body
CSeg Menampilkan metode serta nomor urut pesan dalam panggilan
From Mengandung identitas pemanggil (caller)
To Mengandung identitas terpanggil (calle)
Via Menampilkan informasi koneksi yang digunakan untuk pengiriman
A-5
Universitas Sumatera Utara
Sebagai contoh berikut ini diberikan message header dari sebuah pesan SIP.
Via: SIP/2.0/UDP pc33.unimed.ac.id;branch=z9hG4bK776asdhds
To: Bob <sip:[email protected]>
From: Alice <sip:[email protected]>;tag=1928301774
Call-ID: [email protected]
CSeq: 314159 INVITE
Contact: <sip:[email protected] >
Content-Type: application/sdp
Content-Length: 142
Berikut adalah penjelasan dari setiap baris header field dari contoh diatas :
• baris Via menunjukkan darimana respons message terhadap request ini
diharapkan berasal, dalam hal ini adalah sebuah proxy server dengan
alamat pc33.unimed.ac.id, sementara parameter branch memberikan
identitas mengenai transaksi yang sedang berlangsung.
• baris To mengandung nama tampilan pengguna serta alamat URI kemana
request message ini ditujukan, dan dalam contoh ini adalah Bob dengan
alamat sip:[email protected].
• baris From menyediakan informasi mengenai nama tampilam pengguna
serta alamat URI darimana request ini berasal, dalam contoh ini adalah
Alice dengan alamat sip:[email protected]. Terdapat pula parameter
tag berupa string acak yang digunakan untuk kepentingan identifikasi
pengguna.
• baris Call-ID mengandung identifier global untuk panggilan yang sedang
berlangsung, berupa kombinasi string acak (a84b4c76e66710) dan alamat
domain pemanggil (pc33.unimed.ac.id).
A-6
Universitas Sumatera Utara
• baris Cseq (Command Sequence) mengandung sebuah bilangan integer
(314159) dan nama Method (INVITE). Nilai Cseq akan dinaikkan untuk
setiap request baru.
• baris Contact mengandung alamat URI yang merepresentasikan rute
langsung untuk menghubungi pemanggil, biasanya dalam format Fully
Qualified Domain Name (FQDN). Dalam contoh ini adalah
sip:[email protected].
• baris Content-type mengindikasikan jenis pesan/media yang terkandung
pada batang tubuh pesan (Message Body), yang dalam contoh ini adalah
sebuah pesan SDP. Tabel A.5 menampilkan beberapa jenis pesan/media
yang dapat terkandung pada batang tubuh pesan SIP beserta nilai yang
harus diberikan pada field value untuk mengindikasikannya.
• baris Content-Length memberikan informasi mengenai panjang batang
tubuh pesan (Body) dalam satuan byte.
Tabel A.5 Beberapa jenis pesan/media serta field value yang digunakan
Jenis pesan/media Field value yang digunakan
SDP application/sdp
Text Plain text/plain
JPEG image/jpeg
MP3 audio/mp3
MPEG video/mpeg
A-7
Universitas Sumatera Utara
A.3 Message Body
Batang tubuh dari pesan SIP dapat memuat berbagai jenis pesan dan untuk
berbagai tujuan, namun yang paling umum adalah pesan SDP untuk
mendeskripsikan sesi media yang akan dibangun saat inisiasi panggilan.
Pesan SDP terdiri dari sejumlah baris teks yang mengandung deskripsi
parameter-parameter sesi yang akan dibangun. Pada setiap baris ini sendiri terdiri
dari dua bagian yang disebut type dan value, dan diantara keduanya dipisahkan
oleh satu karakter sama dengan (“=”). Syntax umum dari pesan protokol SDP ini
dapat disusun sebagai berikut.
type=value
Type menunjukkan jenis parameter yang akan dideskripsikan, dan terdiri
dari satu karakter yang bersifat case-significant. Sedangkan value mengandung
nilai parameter dengan syntax yang berbeda untuk setiap jenis parameter yang
dideskripsikan.
Parameter-parameter yang akan dideskripsikan dibagi kedalam tiga
kelompok, yaitu Session Description, Time Description, dan Media Description.
Session Description mengandung informasi mengenai sesi yang akan dibangun,
dan bersifat global untuk keseluruhan sesi dan media stream yang dideskripsikan.
Hanya boleh terdapat satu bagian Session Description dalam sebuah pesan SDP.
Gambar A.2 (a) menampilkan parameter-parameter yang termasuk dalam
kelompok Session Description. Time Description mengandung informasi
mengenai waktu sesi berlangsung. Gambar A.2 (b) menampilkan parameter-
A-8
Universitas Sumatera Utara
parameter yang termasuk dalam kelompok Time Description. Media Description
mengandung informasi mengenai media stream yang akan dibangun pada sesi.
Sebuah pesan SDP dapat mendeskripsikan lebih dari satu media stream dengan
menyertakan sejumlah Media Description, namun pada tugas akhir ini hanya
membahas penggunaan satu media stream. Gambar A.2 (c) menampilkan
parameter-parameter yang termasuk dalam kelompok Media Description.
Beberapa parameter yang ditampilkan pada Gambar A.2 yang ditandai oleh *
bersifat opsional dan tidak harus ada dalam sebuah pesan SDP.
Baris Version (v) menunjukkan versi mayor protokol SDP yang
digunakan. Nilai nol memiliki arti versi protokol SDP yang digunakan sesuai
dengan spesifikasi yang terdapat pada dokumen RFC 2327.
A-9
Session Description Time Description Media Description
Kode Deskripsi Kode Deskripsi Kode Deskripsi
v Version t Active time m Media name
o Owner/session ID r * Repeate time i * Media title
s Session name (b) c * Connection info
i * Session info b * Bandwidth info
u * URI of description k * Encryption key
e * Email address a * Media attribute
p * Phone number (c)
c Connection info
b * Bandwidth info
z * Time zone
a * Session attribute * = opsional
(a)
Gambar A.2 Parameter-parameter protokol SDP
Universitas Sumatera Utara
Baris Origin (o) mengandung informasi mengenai pencipta sesi
(originator), dan nilainya disusun menggunakan syntax sebagai berikut.
<username> <session-id> <version> <network-type> <address-type> <address>
• Username biasanya diambil dari nama login dari pemanggil, atau
dikosongkan (-) apabila nama login tidak tersedia.
• Session-id merupakan string numerik yang berfungsi sebagai identifier
untuk sesi media yang akan dibangun. Nilai untuk session-id ini umumnya
diperoleh dari waktu Network Time Protocol (NTP) yang menghitung
waktu sebagai jumlah detik mulai dari tanggal 1 january 1900 (sesuai
spesifikasi RFC 2327).
• Version menunjukkan nomor urut pesan ini dalam sesi yang dibangun.
• Network-type menunjukkan jenis jaringan data yang akan digunakan pada
sesi media, dan secara default bernilai IN yang berarti sesi akan
menggunakan jaringan Internet.
• Address-type menunjukkan jenis pengalamatan yang digunakan, dan
secara default bernilai IP4 yang menunjukkan sesi akan menggunakan
protokol IP versi 4.
• Address merupakan alamat IP dari pencipta sesi.
Baris Session Name (s) merupakan pengenal untuk sesi yang dibangun.
Dokumen RFC 2327 menspesifikasikan bahwa harus terdapat satu dan hanya satu
baris Session Name pada setiap pesan SDP.
A-10
Universitas Sumatera Utara
Baris Connection Data (c) menunjukkan informasi sambungan yang
digunakan pada sesi yang dibangun, dan nilainya disusun menggunakan syntax
sebagai berikut.
<network-type> <address-type> <connection-address>
• Network Type menunjukkan jenis jaringan yang digunakan, dan secara
default bernilai IN yang berarti sesi akan menggunakan jaringan Internet.
• Address Type menunjukkan jenis protokol pengalamatan yang digunakan,
dan secara default bernilai IP4 yang menunjukkan penggunaan protokol IP
versi 4.
• Connection Address merupakan alamat IP dimana sesi media akan
dikirimkan dan diterima.
Dokumen RFC 2327 menspesifikasikan bahwa setiap pesan SDP harus
mengandung sedikitnya satu connection data pada setiap media description, atau
hanya satu apabila disertakan pada session description.
Baris Time Description (t) menampilkan waktu mulai dan akhir sesi.
Karena waktu mulai dan penutupan sesi tidak ditentukan (dibatasi) secara
langsung, maka baris ini akan bernilai 0 (awal dan akhir).
Baris media name (m) mengandung informasi mengenai media yang
digunakan pada sesi, dan nilainya (value) disusun menggunakan syntax sebagai
berikut.
<media-type> <port> <transport> <format-list>
A-11
Universitas Sumatera Utara
• Media-type menunjukkan jenis media yang digunakan. Dokumen RFC
2327 menspesifikasikan jenis-jenis media yang dapat dibangun adalah
audio, video, application, data, dan control.
• Port menunjukkan nomor port dimana media stream akan dikirimkan
• Transport menunjukkan protokol yang digunakan untuk mengirimkan
media stream. Dokumen RFC 2327 menspesifikasikan protokol yang
dapat digunakan adalah UDP, RTP/AVP (Realtime Transport Protocol
using the Audio/Video Profile Carried over UDP), serta RTP/SAVP (.
• Format list menggambarkan format media yang digunakan. Apabila
bagian transport menggunakan RTP/AVP, maka bagian ini akan
mengandung nomor RTP Payload Type dari format media. Daftar lengkap
Payload Type untuk setiap format media apabila menggunakan RTP/AVP
diberikan pada Lampiran A. Pada contoh, nilai 0 menunjukkan format
pengkodean yang digunakan adalah PCMU (G.711-uLaw).
Informasi tambahan untuk sesi media yang dibangun akan diberikan pada
baris Attribute. Sebuah pesan SDP dapat mengandung satu atau lebih baris
Attribute pada bagian Session Description dan Media Description. Baris Attribute
pada bagian Session Description akan berlaku untuk keseluruhan sesi dan media
stream, sedangkan baris Attribute pada bagian Media Description hanya berlaku
pada media stream yang dideskripsikan. Tabel A.6 menampilkan daftar nilai yang
dapat diberikan pada baris Attribute ini.
A-12
Universitas Sumatera Utara
Tabel A.6 Nilai Attribute yang sesuai
Nilai Attribute Keterangan
sendrecvMendeskripsikan media stream berlangsung
dua arah
sendonlyMendeskripsikan media stream berlangsung satu arah, hanya berasal dari pencipta sesi
recvonlyMendeskripsikan media stream berlangsung
satu arah, ditujukan hanya kepada pencipta sesi
rtpmap Mendeskripsikan format media
Baris Attribute rtpmap mengandung keterangan (informasi) tambahan
mengenai format pengkodean yang digunakan pada media. Berikut adalah syntax
yang digunakan untuk nilai (value) baris Attribute rtpmap yang diperoleh dari
dokumen RFC2327.
rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters>]
• Payload type menunjukkan nomor format pengkodean yang akan
diterangkan pada baris Attribute rtpmap ini.
• Encoding name menerangkan mengenai nama format pengkodean yang
digunakan.
• Clock-rate menerangkan mengenai laju pencuplikan yang digunakan oleh
format pengkodean.
• Encoding parameter dapat digunakan untuk menerangkan berbagai
parameter-parameter lainnya seperti jumlah saluran audio (channel) yang
dibangun .
A-13
Universitas Sumatera Utara
Pesan SDP harus diawali oleh bagian Session Description, diikuti Time
Description dan satu atau lebih Media Description. Setiap bagian disusun sesuai
urutannya sebagaimana ditunjukkan pada Gambar A.2. Bagian Session
Description akan diawali oleh baris Version (v), dan setiap Media Description
akan diawali oleh baris Media Name (m). Berikut adalah sebuah contoh pesan
SDP yang mengandung parameter-parameter minimal yang dibutuhkan untuk
mendeskripsikan sebuah sesi.
v = 0o = alice 1279124485 1 IN IP4 192.168.0.1c = IN IP4 192.168.0.1t = 0 0m = audio 5000 RTP/AVP 0a = sendrecva = rtpmap:0 PCMU/8000
A-14
Universitas Sumatera Utara
LAMPIRAN B
Struktur Kelas Pustaka OPAL
Pustaka OPAL merupakan sebuah pustaka kelas bahasa C++ yang terdiri
dari sejumlah kelas-kelas pemrograman. Kelas-kelas pustaka OPAL ini secara
umum dapat dibagi menjadi dua bagian, yaitu bagian pensinyalan dan bagian
media.
B.1 Bagian Pensinyalan
Bagian pensinyalan dari pustaka OPAL berfungsi menangani
pembentukan (inisiasi) panggilan, penutupan panggilan, serta fungsi-fungsi
pensinyalan telepon lainya. Bagian ini terdiri dari enam kelas utama, yaitu
OpalManager, OpalEndPoint, OpalConnection, dan OpalCall, OpalTransport, dan
OpalListener.
1. OpalManager
Kelas OpalManager merupakan pusat pengaturan dalam sistem yang
menggunakan OPAL. Kelas OpalManager akan mengatur dan memonitor
seluruh komponen lainnya yang terdapat pada sistem serta bertanggung
jawab pada mekanisme panggilan. Setiap aplikasi yang dibuat
menggunakan pustaka OPAL harus memiliki satu objek dari kelas turunan
OpalManager.
B-1
Universitas Sumatera Utara
2. OpalEndPoint
Kelas OpalEndPoint merupakan kelas abstraksi dasar dari seluruh kelas
endpoint yang disediakan OPAL. Implementasi yang lebih spesifik untuk
setiap endpoint diberikan pada kelas-kelas turunan OpalEndPoint. Gambar
B.1 menampilkan turunan-turunan dari kelas OpalEndPoint ini. Aplikasi
dapat memiliki sejumlah objek kelas turunan OpalEndPoint yang
semuanya terhubung (attached) pada OpalManager.
3. OpalConnection
Kelas OpalConnection merupakan kelas abstraksi dasar dari seluruh
sambungan (connection) dari endpoint yang disediakan OPAL.
Implementasi yang lebih spesifik untuk setiap sambungan dari endpoint
diberikan pada kelas-kelas turunan OpalConnection. Gambar B.2
menampilkan turunan-turunan dari kelas OpalConnection ini.
Kelas-kelas turunan OpalConnection ini akan diciptakan oleh kelas-kelas
turunan OpalEndPoint yang bersesuaian ketika pembentukan panggilan.
B-2
Gambar B.1 Kelas-kelas turunan OpalEndPoint
Gambar B.2 Kelas-kelas turunan OpalConnection
Universitas Sumatera Utara
Sebagai contoh, objek kelas SIPConnection akan diciptakan oleh objek
kelas SIPEndPoint ketika sebuah panggilan dibangun menggunakan
protokol SIP.
4. OpalCall
Kelas OpalCall mewadahi sebuah panggilan yang sedang berlangsung.
Kelas ini terdiri dari nol atau lebih objek kelas turunan OpalConnection.
Kelas ini dapat pula meneruskan panggilan, menahan panggilan, dan
fungsi-fungsi pengaturan panggilan yang mirip lainnya. Objek kelas
OpalCall diciptakan oleh OpalManager ketika akan memulai panggilan,
dan akan segera dimusnahkan ketika panggilan berakhir.
5. OpalTransport
Kelas OpalTransport berfungsi menangani pengiriman dan penerimaan
pesan-pesan VoIP melalui jaringan pada pustaka OPAL. Kelas ini
merupakan kelas abstraksi dasar dari seluruh implementasi transport yang
ada di pustaka OPAL. Implementasi yang lebih spesifik ditangani oleh
kelas turunan OpalTransport seperti OpalTransportUDP dan
OpalTransportTCP. Gambar B.3 menampilkan turunan-turunan dari kelas
OpalTransport ini.
B-3
Gambar B.3 Kelas-kelas turunan OpalTransport
Universitas Sumatera Utara
6. OpalListener
Kelas OpalListener berfungsi mendengar sambungan yang masuk pada
transport tertentu, dan melepasnya dalam sebuah thread baru berdasarkan
pada kelas OpalTransport yang sebenarnya.
Kelas ini merupakan kelas dasar dari seluruh implementasi listener yang
ada di pustaka OPAL, dimana terdapat sebuah kelas turunan OpalListener
untuk setiap transport. Gambar B.4 menampilkan turunan-turunan dari
kelas OpalListener ini.
B.2 Bagian Media
Bagian Media dari pustaka OPAL berfungsi mengani pertukaran data
media diantara peserta panggilan. Terdapat tiga kelas yang termasuk dalam
bagian ini, yaitu OpalMediaStream, OpalMediaPatch, dan OpalMediaFormat.
1. OpalMediaStream
Kelas OpalMediaStream merupakan kelas abstraksi dasar dari seluruh
media stream yang didukung pustaka OPAL. Implementasi yang spesifik
untuk setiap media stream diberikan pada kelas-kelas turunan
B-4
Gambar B.4 Kelas-kelas turunan OpalListener
Universitas Sumatera Utara
OpalMediaStream ini. Gambar B.5 menampilkan turunan-turunan dari
kelas OpalMediaStream ini.
Kelas OpalAudioMediaStream digunakan untuk mengirimkan data media
audio dari dan ke perangkat keras suara. Sementara kelas
B-5
Gambar B.5 Kelas-kelas turunan OpalMediaStream
Universitas Sumatera Utara
OpalRTPMediaStream digunakan untuk mengirimkan data media dari dan
ke jaringan melalui sebuah sesi media RTP. Objek kelas ini akan dibangun
oleh objek kelas OpalConnection ketika pembentukan panggilan.
2. OpalMediaFormat
Kelas OpalMediaFormat mendeskripsikan format pengkodean media yang
digunakan untuk mengirimkan dan menerima data media pada pustaka
OPAL. Setiap endpoint umumnya memiliki set format media default yang
akan digunakan ketika panggilan dibentuk menggunakan sambungan dari
endpoint tersebut. Namun, format media yng digunakan dapat pula
ditentukan secara eksplisit pada level aplikasi. Gambar B.6 menampilkan
turunan-turunan dari kelas OpalMediaFormat ini.
3. OpalMediaPatch
Kelas OpalMediaPatch berfungsi mengendalikan pengiriman data media
dari dan ke media stream. Sebagai contoh, sebuah objek OpalMediaPatch
menerima data media dari OpalAudioMediaStream, dan mengirimkannya
ke OpalRTPMediaStream. Kelas ini juga bertanggung jawab memanggil
codec yang sesuai untuk setiap media stream.
B-6
Gambar B.6 Kelas-kelas turunan OpalMediaFormat
Universitas Sumatera Utara
LAMPIRAN C
Metode Pertukaran Kunci Protokol TLS
Terdapat empat metode key exchange yang dapat digunakan pada protokol
TLS, yaitu RSA, Anonymous DH (Diffie Hellman), Ephemeral DH, serta Fixed
DH. Metode key exchange yang akan digunakan sendiri tergantung pada hasil
negosiasi yang dilakukan saat proses handshake. Ilustrasi dari keempat metode ini
ditampilkan pada Gambar C.1
C.1 RSA
Pada metode ini, server akan mengirimkan sertifikat digital yang
mengandung kunci publik RSA miliknya melalui pesan Certificate. Client yang
menerima pesan ini selanjutnya membuat sebuah premaster secret, lalu
mengenkripsinya menggunakan kunci publik RSA milik server, dan
mengirimkannya melalui pesan ClientKeyExchange. Dalam metode ini server
tidak perlu mengirimkan pesan ServerKeyExchange karena premaster secret telah
disediakan oleh client. Metode ini ditampilkan pada Gambar C.1 (a).
C.2 Anonymous DH
Metode ini tidak menggunakan sertifikat. Parameter-parameter Diffie
Hellman dan half-key milik server (g, p, gs) akan dikirimkan melalui pesan
ServerKeyExchange. Client kemudian membalas dengan mengirimkan parameter-
parameter Diffie Hellman dan half-key miliknya (g, p, gc) melalui pesan
ClientKeyExchange. Client dan server kemudian akan menghitung premastester
C-1
Universitas Sumatera Utara
secret berdasarkan parameter-parameter dan half-key ini. Metode ini ditampilkan
pada Gambar C.1(b).
C.3 Ephemeral DH
Pada metode ini, server akan mengirimkan sertifikat tanda tangan digital
RSA atau DSA miliknya melalui pesan Certificate serta parameter-parameter
C-2
Gambar C.1 Metode pertukaran kunci pada protokol TLS
Universitas Sumatera Utara
Diffie Hellman dan half-key (g, p, gs) yang telah ditanda tangani melalui pesan
ServerKeyExchange. Client kemudian akan melakukan verifikasi terhadap tanda
tangan ini menggunakan kunci publik server yang terdapat pada sertifikat.
Client umumnya juga akan mengirimkan sertifikat tanda tangan RSA atau
DSA miliknya melalui pesan Certificate dan parameter-parameter Diffie Hellman
serta half-key (g, p, gc) yang telah ditanda tangani melalui pesan
ClientKeyExchange. Server kemudian akan melakukan verifikasi terhadap tanda
tangan ini menggunakan kunci publik client yang terdapat pada sertifikat.
Penggunaan tanda tangan ini berfungsi untuk otentikasi server dan client.
Client dan Server kemudian akan menghitung premaster secret
berdasarkan parameter-parameter dan half-key. Metode ini ditampilkan pada
Gambar C.1 (c).
C.4 Fixed DH
Pada metode ini server akan mengirimkan sertifikat tanda tangan digital
RSA atau DSA yang juga mengandung parameter-parameter Diffie Hellman dan
half-key (g, p, gs) melalui pesan Certificate. Client kemudian menjawab dengan
mengirimkan pesan Certificate yang mengandung parameter-parameter Diffie
Hellman dan half-key miliknya (g, p, gc). Client dan server kemudian akan
menghitung premastester secret berdasarkan parameter-parameter dan half-key
ini. Tidak ada pesan ServerKeyExchange atau ClientKeyExchange yang dikirim
pada metode ini. Metode ini ditampilkan pada Gambar C.1 (d).
C-3
Universitas Sumatera Utara
LAMPIRAN D
Mekanisme Perhitungan Kunci Protokol TLS
Protokol TLS menghitung material kunci berdasarkan nilai premaster
secret serta bilangan acak Client Random dan Server Random yang dihasilkan
masing-masing oleh client dan server saat proses handshake. Perhitungan akan
dilakukan menggunakan sebuah fungsi yang dinamakan PRF (Pseudorandom
Function), dan dilakukan dalam dua langkah sebagai ditampilkan pada Gambar
D.1
Langkah pertama adalah menghasilkan master secret menggunakan fungsi
PRF, dimana masukan yang diberikan berupa premaster secret, sebuah string
ASCII “master secret”, serta gabungan dari Cient Random dan Server Random.
Master secret yang dihasilkan akan berukuran 48 byte, sehingga perlu
dikembangkan (ekspansi) menggunakan fungsi PRF kembali untuk dapat
D-1
Gambar D.1 Mekanisme Perhitungan Kunci
Universitas Sumatera Utara
dijadikan material kunci. Kali ini yang menjadi masukan adalah master secret
yang baru saja dihasilkan, sebuah string ASCII “key expansion”, serta gabungan
Server Random dan Client Random.
Material kunci yang dihasilkan sekarang akan dibagi menjadi beberapa
kunci sesuai dengan penggunaannya sebagai berikut
• Client_MAC_Write_Key, digunakan oleh client untuk menghitung MAC
• Server_MAC_Write_Key, digunakan oleh server untuk menghitung MAC
• Client_Write_Key, digunakan oleh client sebagai kunci untuk enkripsi
• Server_Write_Key, digunakan oleh server sebagai kunci untuk enkripsi
Perlu diingat bahwa kunci-kunci tersebut digunakan secara berpasangan.
Sebagai contoh, Server_Write_Key akan digunakan oleh client untuk mendekripsi
(membaca) pesan yang diterima dari server. Sedangkan Client_Write_Key akan
digunakan oleh server untuk mendekripsi (membaca) pesan yang diterima dari
client. Demikian pula pada Client_MAC_Write_Key dan
Client_MAC_Write_Key.
D.1 Pseudorandom Function (PRF)
Fungsi ini digunakan oleh protokol TLS untuk menghasilkan keluaran
berupa bilangan acak (pseudorandom). Fungsi ini sendiri dikembangkan
menggunakan basis algoritma HMAC yang telah dijelaskan diawal, dan algoritma
lengkapnya ditampilkan pada Gambar D.2
D-2
Universitas Sumatera Utara
Fungsi inilah yang kemudian digunakan untuk membangun fungsi PRF,
dengan mengkombinasikan dua prosedur dengan fungsi hash yang berbeda. Hal
ini dilakukan untuk mengatasi kelemahan pada setiap fungsi hash. Fungsi hash
yang umumnya digunakan adalah MD5 dan SHA. Gambar D.3 mengilustrasikan
algoritma Pseudorandom Function (PRF) menggunakan fungsi hash MD5 dan
SHA.
D-3
Gambar D.2 Pseudorandom Generator
Gambar D.3 Pseudorandom Function
Universitas Sumatera Utara
PRF pada protokol TLS membutuhkan masukan berupa kunci secret, seed,
dan label. Kunci secret akan dibagi menjadi dua, masing-masing untuk setiap
prosedur pseudorandom. Fungsi PRF juga akan menggabungkan label dan seed
menjadi sebuah nilai tunggal. Pada kasus dimana fungsi hash yang digunakan
adalah MD5 dan SHA yang memiliki keluaran berbeda, jumlah iterasi yang
dilakukan mungkin saja berbeda.
D-4
Universitas Sumatera Utara
LAMPIRAN E
Implementasi Protokol TLS pada Aplikasi Menggunakan OpenSSL API
Untuk membangun sebuah sambungan TLS pada aplikasi menggunakan
OpenSSL dibutuhkan beberapa langkah sebagaimana ditampilkan pada diagram
alir Gambar E.1. Langkah-langkah yang dilakukan sedikit berbeda antara client
dan server.
E-1
Gambar E.1 Diagram alir membangun sambungan TLS dengan OpenSSL
Universitas Sumatera Utara
E.1 Membangun struktur parameter sesi dan sambungan (server dan client)
Sebuah pointer dengan tipe SSL_CTX diperlukan untuk menampung
struktur parameter-parameter sesi. Struktur ini diciptakan dengan memanggil
fungsi SSL_CTX_new dengan argumen berupa metode dan protokol yang akan
dibangun. Karena protokol yang digunakan adalah TLS versi 1.0 maka metode
yang digunakan disini adalah TLSv1_server_method pada sisi server, dan
TLSv1_client_method pada sisi client. Sebuah pointer lainnya dengan tipe SSL
kemudian diciptakan untuk menampung struktur sambungan SSL.
SSL_CTX * ctx = SSL_CTX_new(TLSv1_server_method());SSL * ssl
E.2 Pengelolaan sertifikat dan kunci privat (server dan client)
Sertifikat diperoleh dengan memanggil fungsi SSL_CTX_use_Certificate
dengan argumen berupa sebuah pointer SSL_CTX yang telah diciptakan
sebelumnya, dan sebuah pointer lainnya yang menunjuk alamat memori dimana
sertifikat dimana. Kemudian kunci privat diperoleh dengan memanggil fungsi
SSL_CTX_use_PrivateKey.
SSL_CTX_use_Certificate(ctx, cert)SSL_CTX_use_PrivateKey (ctx, privatekey)
E.3 Membuka saluran I/O untuk sambungan (server dan client)
OpenSSL menggunakan sebuah kelas abstraksi yang disebut BIO untuk
menangani komunikasi jaringan melalui socket. Pada sisi server akan diciptakan
tiga objek BIO, masing-masing untuk mendengar dan menerima sambungan
masuk, memberikan balasan untuk sambungan yang masuk, dan sebuah objek
E-2
Universitas Sumatera Utara
utama yang menggunakan struktur parameter sesi TLS yang telah dibangun
sebelumnya. Objek utama ini diciptakan dengan memanggil fungsi BIO_new_ssl
dengan argumen berupa pointer dengan tipe SSL_CTX yang menunjuk struktur
parameter sesi serta sebuah flag yang menjelaskan tipe objek BIO yang akan
diciptakan. Nilai flag 0 digunakan untuk server, sedangkan nilai flag 1 digunakan
untuk client. Pointer dengan tipe SSL yang akan digunakan sebagai struktur
sambungan kemudian dipanggil melalui fungsi BIO_get_ssl().
BIO *bio, *abio, *out;bio = BIO_new_ssl(ctx, 0);BIO_get_ssl(bio, &ssl);
E.4 Mendengar sambungan masuk (server)
Objek BIO untuk mendengar dan menerima sambungan masuk diciptakan
dengan memanggil fungsi BIO_new_accept dengan argumen berupa alamat port
dimana sambungan masuk akan didengar. Karena menggunakan sambungan
aman, maka objek ini harus dihubungkan dengan objek BIO utama dengan
memanggil fungsi BIO_set_accept_bios.
abio = BIO_new_accept("4422");BIO_set_accept_bios(abio, bio);
Objek ini akan mulai mendengar sambungan masuk dengan memanggil
fungsi BIO_do_accept dua kali berturut-turut. Panggilan pertama akan
menyebabkan objek menerima sambungan masuk, dan panggilan kedua akan
membuat objek menunggu sambungan masuk
BIO_do_accept(abio);BIO_do_accept(abio);
E-3
Universitas Sumatera Utara
E.5 Menginisialisasi sambungan (client)
Sambungan TLS dibangun melalui sebuah objek BIO dengan memanggil
fungsi BIO_new_ssl_connect. Fungsi ini membutuhkan sebuah argumen berupa
pointer dengan tipe SSL_CTX yang mengandung informasi-informasi sesi. Objek
BIO ini kemudian akan menggunakan struktur SSL yang telah diciptakan
sebelumnya dengan memanggil fungsi BIO_get_ssl().
bio = BIO_new_ssl_connect(ctx);BIO_get_ssl(bio, & ssl);
Alamat hostname (server) kemudian diatur melalui fungsi
BIO_set_conn_hostname, dan sambungan dapat segera dibuka dengan memangil
fungsi BIO_do_connect. Fungsi ini juga akan memulai proses handshake.
BIO_set_conn_hostname(bio, "hostname:port");BIO_do_connect(bio);
E.6 Menjawab sambungan masuk (server)
Sambungan yang masuk pada server akan dijawab oleh objek BIO
lainnya. Objek ini diciptakan dengan memanggil fungsi BIO_pop dengan
argumen berupa objek BIO yang mendengar sambungan masuk. Hal pertama
yang akan dilakukan oleh objek ini ketika sebuah sambungan masuk adalah
menangani proses handshake dengan memanggil fungsi BIO_do_handshake
out = BIO_pop(abio);BIO_do_handshake(out);
E.7 Mengirim dan Menerima data melalui sambungan (server dan client)
Pembacaan dan penulisan melalui sambungan yang telah terbentuk
dilakukan dengan memanggil fungsi BIO_read dan BIO_write. Fungsi BIO_read
E-4
Universitas Sumatera Utara
akan mencoba membaca sejumlah data dari sambungan dan akan mengembalikan
jumlah byte data yang berhasil terbaca. Fungsi ini akan mengembalikan nilai -1
apabila terjadi kesalahan (error).
int r = BIO_read(bio, buf, len);int w = BIO_write(bio, buf, len)
Fungsi BIO_write akan mencoba mengirimkan sejumlah data melalui
sambungan yang telah terbentuk, dan akan mengembalikan jumlah byte yang
berhasil dikirimkan. Seperti juga pada fungsi BIO_read, fungsi ini akan
mengembalikan nilai -1 apabila terjadi kesalahan (error).
E.8 Menutup sambungan (server & client)
Sambungan yang telah terbentuk ditutup dengan memanggil fungsi
BIO_reset. Fungsi ini akan menutup sambungan dan mengembalikan kondisi
internal objek BIO seperti semula sehingga sambungan dapat digunakan kembali.
BIO_reset(bio);
E-5
Universitas Sumatera Utara
LAMPIRAN F
Referensi Kelas PIndirectChannel dari Pustaka PTLIB
1. Deskripsi
Kelas ini merupakan sebuah saluran I/O (input/output) yang bekerja secara
tidak langsung melalui saluran-saluran lain. Kelas ini memungkinkan sebuah
protokol untuk bekerja menggunakan mekanisme saluran, sementara pertukaran
byte level rendah dilakukan melalui saluran lain seperti TCP atau Serial Port, dll.
Kelas ini merupakan turunan dari kelas PChannel, yang diturunkan dari
kelas PObject. Gambar B.1 berikut menampilkan diagram inheritance kelas
PIndirectChannel.
V-1
Gambar B.1 Diagram inheritance kelas PIndirectChannel
Universitas Sumatera Utara
2. Dokumentasi Metode dan Variabel
Metode-metode Public
Konstruktor & Destruktor
PIndirectChannel::PIndirectChannel ( )
Keterangan :Konstruktor yang dipanggil ketika instanisasi objek PIndirectChannel. Akan membuat sebuah saluran tidak langsung (indirect channel) tanpa satu saluran pun untuk pengalihan
PIndirectChannel::~PIndirectChannel ( )
Keterangan :Destruktor yang dipanggil ketika pemusnahan objek PIndirectChannel. Berfungsi menutup saluran yang bersangkutan, serta memusnahkan saluran baca/tulis apabila diinginkan
Override dari kelas PObject
Comparison PIndirectChannel::Compare ( const PObject & obj ) const
Keterangan :berfungsi membandingkan apakah kedua objek merujuk pada saluran tidak langsung yang sama atau tidak.Diimplementasikan ulang dari PChannel
Keluaran:EqualTo apabila saluran sama (identik)
Parameter:obj = saluran tidak langsung lainnya yang menjadi perbandingan
Override dari kelas PChannel
virtual PString PIndirectChannel::GetName ( ) const
Keterangan :Berfungsi mengambil nama dari saluran bersangkutan. Diimplementasikan ulang dari Pchannel
Keluaran :String nama saluran
V-2
Universitas Sumatera Utara
virtual PBoolean PIndirectChannel::Close ( )
Keterangan :Berfungsi menutup saluran. Metode ini akan melepaskan saluran yang bersangkurandari saluran baca and tulis.Diimplementasikan ulang dari Pchannel
Keluaran:PTrue apabila saluran berhasil tertutup
virtual PBoolean PIndirectChannel::Shutdown ( ShutdownValue option )
Keterangan :berfungsi menutup salah satu atau kedua aliran data (pembacaan atau penulisan) yang terkait dengan sebuah saluran
Keluaran :PTrue jika penutupan sukses
Parameter :option = penanda (flag) untuk menutup pembacaan, penulisan, atau keduanya
virtual PBoolean PIndirectChannel::Read ( void * buf, PINDEX len)
Keterangan :Berfungsi melakukan pembacaan tingkat rendah dari saluran. Metode ini mungkin akan menghalangi (block) jalannya program hingga sejumlah karakter yang diminta terbaca atau timeout pembacaan tercapai. Metode GetLastReadCount( ) dapat digunakan untuk mengetahui jumlah bytes yang terbaca sebenarnya.
Metode ini sesungguhnya akan menggunakan readChannel untuk pembacaan
Metode GetErrorCode( ) sebaiknya dipanggil apabila Read( ) mengembalikan nilai PFalse untuk mengetahui penyebab kegagalan.
Diimplementasikan ulang dari PChannel
Keluaran :PTrue apabila ada setidaknya satu karakter data yang terbaca dari saluran. PFalse apabila tidak ada data yang terbaca hingga timeout atau karena sejumlah kesalahan I/O lainnya.
Parameter :buf = pointer menuju blok memory penyangga (buffer) untuk menyimpan data yang terbacalen = jumlah maksimum data yang terbaca yang dapat disimpan ke penyangga (buffer)
V-3
Universitas Sumatera Utara
virtual PBoolean PIndirectChannel::Write ( void * buf, PINDEX len )
Keterangan :Berfungsi melakukan penulisan tingkat rendah ke saluran. Metode ini mungkin akan menghalangi (block) jalannya program hingga sejumlah karakter yang diminta dituliskan atau timeout penulisan tercapai. Metode GetLastWriteCount( ) dapat digunakan untuk mengetahui jumlah bytes yang berhasil dituliskan sebenarnya.
Metode ini sesungguhnya akan menggunakan writeChannel untuk penulisan.
Metode GetErrorCode( ) sebaiknya dipanggil apabila Write( ) mengembalikan nilai PFalse untuk mengetahui penyebab kegagalan.
Diimplementasikan ulang dari PChannel
Keluaran :PTrue apabila ada setidaknya satu karakter data yang berhasil ditulis ke saluran. PFalse apabila tidak ada data yang berhasil ditulis hingga timeout atau karena sejumlah kesalahan I/O lainnya.
Parameter :buf = pointer ke blok memory penyangga (buffer) yang menyimpan data yang akan ditulislen = jumlah maksimum data dari penyangga yang akan ditulis ke saluran
virtual PChannel* PIndirectChannel::GetBaseReadChannel ( ) const
Keterangan :Berfungsi mengambil saluran dasar terakhir untuk pembacaan dari serangkaian saluran tidak langsung yang disediakan oleh turunan PIndirectChannel Diimplementasikan ulang dari Pchannel
Keluaran :Pointer ke saluran dasar
virtual PChannel* PIndirectChannel::GetBaseWriteChannel ( )
Keterangan :Berfungsi mengambil saluran dasar terakhir untuk penulisan dari serangkaian saluran tidak langsung yang disediakan oleh turunan PIndirectChannel Diimplementasikan ulang dari PChannel
Keluaran :Pointer ke saluran dasar
V-4
Universitas Sumatera Utara
virtual PString PIndirectChannel::GetErrorText ( ErrorGroup group ) const
Keterangan :Berfungsi mengambil deskripsi pesan kesalahan. Akan mengembalikan sebuah string yang mengindikasikan pesan kesalahan yang bisa dimengerti pengguna.
Keluaran :String deskripsi kesalahan sistem operasi
Parameter :group = kelompok kesalahan yang akan diambil deskripsinya
virtual PBoolean PIndirectChannel::IsOpen ( ) const
Keterangan :Berfungsi menguji apakah saluran telah terbuka dan operasi baca tulis dapat dilakukanDiimplementasikan ulang dari Pchannel
Keluaran :PTrue jika saluran terbuka
Metode-metode untuk pembentukan saluran (channel)
PChannel * PIndirectChannel::GetReadChannel ( ) const
Keterangan :Berfungsi mengambil saluran yang digunakan untuk operasi baca
Keluaran :Pointer ke saluran baca
PBoolean PIndirectChannel::SetReadChannel ( PChannel * channel, Pboolean autoDelete = PTrue )
Keterangan :Berfungsi menyetel saluran untuk operasi baca
keluaran :PTrue apabila saluran telah diatur dan terbuka
parameter :channel = saluran yang akan digunakan untuk operasi bacaautoDelete = menghapus saluran secara otomatis
PChannel * PIndirectChannel::GetWriteChannel ( ) const
Keterangan :Berfungsi mengambil saluran yang digunakan untuk operasi tulis (kirim)
Keluaran :Pointer ke saluran tulis
V-5
Universitas Sumatera Utara
PBoolean PIndirectChannel::SetWriteChannel ( PChannel * channel, PBoolean autoDelete = PTrue )
Keterangan :Berfungsi menyetel saluran untuk operasi tulis
Keluaran :PTrue apabila saluran telah diatur dan terbuka
Parameter :channel = saluran yang akan digunakan untuk operasi tulisautoDelete = menghapus saluran secara otomatis
PBoolean PIndirectChannel::Open ( PChannel * readChannel, PChannel * writeChannel, PBoolean autoDeleteRead = PTrue, PBoolean autoDeleteWrite = PTrue )
Keterangan :Berfungsi menyetel saluran untuk operasi baca dan tulis. Metode ini lalu akan menguji apakah saluran telah terbuka dan memanggil OnOpen( ). Apabila metode OnOpen( ) mengembalikan PTrue maka metode Open( ) kembali dengan sukses.
Keluaran :PTrue jika kedua saluran telah diatur dan terbuka, serta OnOpen( ) mengembalikan nilai Ptrue
Parameter :readChannel = saluran untuk operasi bacawriteChannel = saluran untuk operasi tulisautoDeleteRead = hapus saluran baca secara otomatisautoDeleteWrite = hapus saluran tulis secara otomatis
PBoolean PIndirectChannel::Open ( PChannel * channel, PBoolean autoDelete = Ptrue )
Keterangan :Berfungsi menyetel saluran untuk operasi baca dan tulis. Metode ini lalu akan menguji apakah saluran telah terbuka dan memanggil OnOpen( ). Apabila metode OnOpen( ) mengembalikan PTrue maka metode Open( ) kembali dengan sukses.
Keluaran :PTrue jika kedua saluran telah diatur dan terbuka, serta OnOpen( ) mengembalikan nilai PTrue
Parameter :channel = saluran untuk operasi baca dan tulisautoDelete = hapus saluran baca dan tulis secara otomatis
V-6
Universitas Sumatera Utara
PBoolean PIndirectChannel::Open ( PChannel & channel )
Keterangan :Berfungsi menyetel saluran untuk operasi baca dan tulis. Metode ini lalu akan menguji apakah saluran telah terbuka dan memanggil OnOpen( ). Apabila metode OnOpen( ) mengembalikan PTrue maka metode Open( ) kembali dengan sukses.
Keluaran :PTrue jika kedua saluran telah diatur dan terbuka, serta OnOpen( ) mengembalikan nilai PTrue
Parameter :channel = saluran untuk operasi baca dan tulis
Metode-metode Protected
virtual PBoolean PIndirectChannel::OnOpen ( )
Keterangan :Akan dipanggil oleh metode Open( ) apabila berhasil membuka saluran. Dapat digunakan oleh saluran turunan untuk melakukan handshaking yang diperlukan oleh protokol yang diwadahinya.
Secara default akan mengembalikan nilai PTrue
Keluaran :PTrue apabila handshaking protokol sukses
Variabel-variabel
PChannel* PIndirectChannel::readChannel
Keterangan :Merupakan pointer menuju saluran (channel) untuk operasi baca
PChannel* PIndirectChannel::writeChannel
Keterangan :Merupakan pointer menuju saluran (channel) untuk operasi tulis/kirim
PBoolean PIndirectChannel::readAutoDelete
Keterangan :flag (penanda) untuk menghapus saluran baca secara otomatis ketika saluran dihapus
PBoolean PIndirectChannel::writeAutoDelete
Keterangan :flag (penanda) untuk menghapus saluran tulis secara otomatis ketika saluran dihapus
V-7
Universitas Sumatera Utara
LAMPIRAN G
Referensi Kelas OpalTransport dari Pustaka OPAL
1. Deskripsi
Kelas ini menggambarkan sebuah transport I/O untuk sebuah protokol
VoIP. Transport sendiri merupakan sebuah objek yang memungkinkan transfer
dan pemrosesan data sebelum satu entitas ke entitas lainnya.
Kelas ini merupakan turunan dari kelas PindirectChannel dari pustaka
PTLIB. Terdapat dua realisasi OpalTransport, yaitu OpalTransportTCP yang
menangani transport untuk protokol TCP, dan OpalTransportUDP yang
menangani transport untuk protokol UDP. Gambar C.1 berikut menampilkan
diagram inheritance kelas OpalTransport.
V-1
Gambar C.1 Diagram inheritance kelas OpalTransport
Universitas Sumatera Utara
2. Dokumentasi Metode dan Variabel
Metode-metode Public
Konstruktor & Destruktor
OpalTransport::OpalTransport ( OpalEndPoint & endpoint )
Keterangan :Konstruktor yang dipanggil ketika instanisasi objek OpalTransport. Akan membuat sebuah saluran transport yang terikat pada endpoint.
Parameter :endpoint = endpoint dimana transport yang bersangkutan akan terpaut
OpalTransport::~OpalTransport ( OpalEndPoint & endpoint )
Keterangan :Destruktor yang dipanggil ketika pemusnahan objek OpalTransport. Akan menghapus saluran transport yang bersangkutan.
Metode-Metode Operasi Transport
virtual void OpalTransport::AttachThread ( PThread * thread )
Keterangan :Berfungsi menambatkan sebuah thread untuk transport bersangkutan
void OpalTransport::CleanUpOnTermination ( )
Keterangan :Berfungsi menutup saluran lalu menunggu thread terkait untuk berhenti. Digunakan untuk kompatibilitas dengan OpenH323 yang telah usang
virtual PBoolean OpalTransport::Close ( )
Keterangan :Berfunsi menutup saluran
void OpalTransport::CloseWait ( )
Keterangan :Berfungsi menutup saluran lalu menunggu thread terkait untuk berhenti.
PBoolean OpalTransport::Connect ( )
Keterangan :Berfungsi membangun sambungan ke alamat remote.Diimplementasikan pada OpalTransportTCP dan OpalTransportUDP
V-2
Universitas Sumatera Utara
PBoolean OpalTransport::ConnectTo ( const OpalTransportAddress & address )
Keterangan :Berfungsi membangun sambungan ke alamat remote tertentu
OpalEndPoint& OpalTransport::GetEndPoint ( ) const
Keterangan :Berfungsi mengambil endpoint dimana transport yang bersangkuran tertambat
virtual PString OpalTransport::GetInterface ( ) const
Keterangan :Berfungsi mengambil interface dimana transport bersangkutan terhubung. Umumnya hanya relevan untuk transport berbasis datagram seperti UDP, sementara TCP selalu terhubung pada interface lokal setiap kali terbuka.Secara default mengembalikan alamat lokal melalui GetLocalAddress ( )Diimplementasikan ulang pada OpalTransportUDP
virtual OpalTransportAddress OpalTransport:: GetLastReceivedAddress ( ) const
Keterangan :Berfungsi mengambil alamat transport darimana PDU yang terakhir diterimaSecara default memanggil GetRemoteAddress( )Diimplementasikan ulang pada OpalTransportUDP
virtual PString OpalTransport::GetLastReceivedInterface ( ) const
Keterangan :Berfungsi mengambil interface dimana PDU terakhir diterima tiba/sampaiSecara default memanggil GetLocalAddress( )Diimplementasikan ulang pada OpalTransportUDP
virtual OpalTransportAddress OpalTransport::GetLocalAddress ( bool allowNAT = true )
Keterangan :Berfungsi mengambil nama transport dari local endpoint
Parameter :allowNAT = memungkinkan translasi apabila remote membutuhkan NAT
diimplementasikan pada OpalTransportIP dan OpalTransportUDP
virtual const char* OpalTransport::GetProtoPrefix ( ) const
Keterangan :Berfungsi mengambil prefix untuk tipe protokol transport yang bersangkutanDiimplementasikan pada OpalTransportIP, OpalTransportUDP, dan OpalTransportTCP
V-3
Universitas Sumatera Utara
virtual OpalTransportAddress OpalTransport::GetRemoteAddress ( ) const
Keterangan :Berfungsi mengambil alamat transport dari endpoint remoteDiimplementasikan pada OpalTransportIP
virtual PBoolean OpalTransport::IsCompatibleTransport (const OpalTransportAddress & address ) const
Keterangan :Berfungsi untuk menguji apakah alamat transport kompatibel (cocok) dengan transport bersangkutanDiimplementasikan pada OpalTransportTCP dan OpalTransportUDP
virtual PBoolean OpalTransport:: IsReliable ( )
Keterangan :Berfungsi untuk memeriksa jenis transport yang mendasari
virtual PBoolean OpalTransport::IsRunning ( )
Keterangan :Berfungsi untuk memeriksa apakah transport berjalan dengan background thread
virtual PBoolean OpalTransport::ReadPDU ( PBYTEArray & packet )
Keterangan :Berfungsi melakukan peembacaan PDU (Protocol Data Unit) dari transport bersangkutan. Pembacaan menggunakan mekanisme transport sesuai batas-batas PDU, misalnya pada UDP merupakan sebuah panggilan tunggal Read( ), sementara pada TCP terdapat sebuah TPKT header yang mengindikasikan ukuran PDU.diimplementasikan pada OpalTransportTCP dan OpalTransportUDP
Parameter :packet = Packet yang dibaca dari transport
virtual bool OpalTransport::SetInterface ( const PString & iface )
Keterangan :berfungsi mengikat transport yang bersangkutan pada sebuah interface. Umumnya hanya relevan untuk transport berbasis datagram seperti UDP, sementara TCP selalu terhubung pada interface lokal setiap kali terbuka.Secara default tidak melakukan apa-apa.Diimplementasikan ulang pada OpalTransportUDP
Parameter:iface = interface yang akan digunakan
V-4
Universitas Sumatera Utara
virtual PBoolean OpalTransport::SetLocalAddress ( const OpalTransportAddress & address )
Keterangan :Berfungsi menyetel alamat lokal darimana akan terhubung. Tidak harus bekerja pada seluruh tipe transport atau hanya bekerja sebelum Connect( ) dipanggil.Diimplementasikan pada OpalTransportIP dan OpalTransportUDP
virtual void OpalTransport::SetPromiscuous ( PromisciousModes promiscuous )
Keterangan :Berfungsi mengatur pembacaan kedalam modus promiscuous. Secara normal hanya membolehkan pembacaan dari alamat remote yang telah ditentukan. Metode ini membolehkan pembacaan paket dari alamat remote manapun asalkan protokol yang mendasari dapat melakukannya, seperti UDP.
virtual PBoolean OpalTransport::SetRemoteAddress ( const OpalTransportAddress & address )
Keterangan :Berfungsi menyetel alamat remote kemana akan terhubung.
virtual PBoolean OpalTransport::WriteConnect ( WriteConnectCallback function, void * userData )
Keterangan :Berfungsi menuliskan paket pertama ke transport setelah terhubung untuk menyesuaikan objek transport. Akan memanggil fungsi callback, mungkin beberapa kali untuk beberapa jenis transport.Diharapkan digunakan segera setelah pemanggilan Connect ( ) dimana beberapa transport (seperti UDP) tidak dapat menentukan local addressnya sendiri yang dibutuhkan pada PDU yang akan dikirim. Hal ini dilakukan untuk setiap interface sehingga WriteConnect( ) memanggil WriteConnectCallback untuk setiap interface. Pemanggilan ReadPDU( ) selanjutnya akan mengembalikan jawaban dari interface pertama.Secara default hanya akan memanggil fungsi WriteConnectCallback
Parameter :function = fungsi untuk menuliskan datauserData = data pengguna untuk dilewatkan ke fungsi write
virtual PBoolean OpalTransport::WritePDU ( const PBYTEArray & pdu )
Keterangan :Berfungsi menuliskan sebuah PDU ke transport, menggunakan mekanisme transport sesuai batas-batas PDU, misalnya pada UDP merupakan sebuah panggilan tunggal Read( ), sementara pada TCP akan menambahkan sebuah TPKT header yang mengindikasikan ukuran PDU.
Parameter :pdu = paket PDU yang akan dituliskan
V-5
Universitas Sumatera Utara
Variabel-variabel
OpalEndPoint& OpalTransport::endpoint
Keterangan : endpoint dimana transport yang bersangkutan tertambat
PThread* OpalTransport::thread
Keterangan :Pointer ke thread yang menangani transport bersangkutan
V-6
Universitas Sumatera Utara
LAMPIRAN H
Listing Kode Program
H.1 Transport TLS (header)
class OpalTransportTLS : public OpalTransportTCP{ PCLASSINFO(OpalTransportTLS, OpalTransportTCP); public:
/// Konstruktor OpalTransportTLS( OpalEndPoint & endpoint, ///< Eobjek endpoint PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), ///< interface lokal yang digunakan WORD port = 0, ///< port lokal yang digunakan PBoolean reuseAddr = PFalse ); /// Destruktor ~OpalTransportTCPS();
PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const; PBoolean Connect(); PBoolean OnOpen(); const char * GetProtoPrefix() const;
protected: tlsContext * sslContext;};
H.2 Transport TLS (implementasi)
OpalTransportTLS::OpalTransportTLS(OpalEndPoint & ep, PIPSocket::Address binding, WORD port, PBoolean reuseAddr) : OpalTransportTCP(ep, binding, port, reuseAddr){ tlsContext = new TLSContext(TLSContext::TLSv1);}
OpalTransportTLS::~OpalTransportTLS(){ CloseWait(); delete tlsContext;}
PBoolean OpalTransportTLS::IsCompatibleTransport(const OpalTransportAddress & address) const{ return OpalTransportTCP::IsCompatibleTransport(address) || address.NumCompare(TlsPrefix) == EqualTo;}
PBoolean OpalTransportTCPS::Connect(){ if (IsOpen()) return PTrue;
V-1
Universitas Sumatera Utara
PTCPSocket * socket = new PTCPSocket(remotePort);
PReadWaitAndSignal mutex(channelPointerMutex);
socket->SetReadTimeout(10000);
OpalManager & manager = endpoint.GetManager(); localPort = manager.GetNextTCPPort();
socket->Connect(localPort, remoteAddress))
int errnum = socket->GetErrorNumber(); if (localPort == 0 || (errnum != EADDRINUSE && errnum != EADDRNOTAVAIL)) { return SetErrorValues(socket->GetErrorCode(), errnum); }
socket->SetReadTimeout(PMaxTimeInterval);
PString certificateFile = endpoint.GetTLSCertificate(); if (!SetTLSCertificate(*sslContext, certificateFile, PTrue)) { return PFalse; }
TLSChannel * tlsChannel = new TLSChannel(tlsContext); if (!tlsChannel->Connect(socket)) { delete tlsChannel; return PFalse; }
return Open(tlsChannel);}
PBoolean OpalTransportTLS::OnOpen(){ TLSChannel * tlsChannel = dynamic_cast<TLSChannel *>(GetReadChannel()); if (tlsChannel == NULL) return PFalse;
PIPSocket * socket = dynamic_cast<PIPSocket *>(sslChannel->GetReadChannel());
if (!socket->GetPeerAddress(remoteAddress, remotePort)) { return PFalse; }
if (!socket->GetLocalAddress(localAddress, localPort)) { return PFalse; }
return PTrue;}
const char * OpalTransportTLS::GetProtoPrefix() const{ return TlsPrefix;}
H.3 TLS Channel (header)
#include <ptlib/sockets.h>
struct ssl_st;struct ssl_ctx_st;struct x509_st;
V-2
Universitas Sumatera Utara
struct evp_pkey_st;struct dh_st;
enum PSSLFileTypes { PSSLFileTypePEM, PSSLFileTypeASN1, PSSLFileTypeDEFAULT};
class PSSLChannel : public PIndirectChannel{ PCLASSINFO(PSSLChannel, PIndirectChannel) public: PSSLChannel( PSSLContext * context = NULL, ///< Context for SSL channel PBoolean autoDeleteContext = PFalse ///< Flag for context to be automatically deleted. ); PSSLChannel( PSSLContext & context ///< Context for SSL channel );
~PSSLChannel();
// Overrides from PChannel virtual PBoolean Read(void * buf, PINDEX len); virtual PBoolean Write(const void * buf, PINDEX len); virtual PBoolean Close(); virtual PBoolean Shutdown(ShutdownValue) { return PTrue; } virtual PString GetErrorText(ErrorGroup group = NumErrorGroups) const; virtual PBoolean ConvertOSError(int error, ErrorGroup group = LastGeneralError);
PBoolean Connect( PChannel * channel, ///< Channel to attach to. PBoolean autoDelete = PTrue ///< Flag for if channel should be automatically deleted.
enum VerifyMode { VerifyNone, VerifyPeer, VerifyPeerMandatory, };
void SetVerifyMode( VerifyMode mode );
PSSLContext * GetContext() const { return context; }
virtual PBoolean RawSSLRead(void * buf, PINDEX & len);
protected: virtual PBoolean OnOpen();
protected: PSSLContext * context; PBoolean autoDeleteContext; ssl_st * ssl;};
H.4 TLS Channel (implementasi)
#pragma implementation "tlsChannel.h"
#include <ptlib.h>
#include <ptclib/pssl.h>#include <ptclib/mime.h>
V-3
Universitas Sumatera Utara
#include <ptbuildopts.h>
#define USE_SOCKETS
extern "C" {
#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/rand.h>
};
PSSLChannel::PSSLChannel(PSSLContext * ctx, PBoolean autoDel){ if (ctx != NULL) { context = ctx; autoDeleteContext = autoDel; } else { context = new PSSLContext; autoDeleteContext = PTrue; }
ssl = SSL_new(*context); if (ssl == NULL) PSSLAssert("Error creating channel: ");}
PSSLChannel::PSSLChannel(PSSLContext & ctx){ context = &ctx; autoDeleteContext = PFalse;
ssl = SSL_new(*context);}
PSSLChannel::~PSSLChannel(){ // free the SSL connection if (ssl != NULL) SSL_free(ssl);
if (autoDeleteContext) delete context;}
PBoolean PSSLChannel::Read(void * buf, PINDEX len){ flush();
channelPointerMutex.StartRead();
lastReadCount = 0;
PBoolean returnValue = PFalse; if (readChannel == NULL) SetErrorValues(NotOpen, EBADF, LastReadError); else if (readTimeout == 0 && SSL_pending(ssl) == 0) SetErrorValues(Timeout, ETIMEDOUT, LastReadError); else { readChannel->SetReadTimeout(readTimeout);
int readResult = SSL_read(ssl, (char *)buf, len); lastReadCount = readResult; returnValue = readResult > 0;
V-4
Universitas Sumatera Utara
if (readResult < 0 && GetErrorCode(LastReadError) == NoError) ConvertOSError(-1, LastReadError); }
channelPointerMutex.EndRead();
return returnValue;}
PBoolean PSSLChannel::Write(const void * buf, PINDEX len){ flush();
channelPointerMutex.StartRead();
lastWriteCount = 0;
PBoolean returnValue; if (writeChannel == NULL) { SetErrorValues(NotOpen, EBADF, LastWriteError); returnValue = PFalse; } else { writeChannel->SetWriteTimeout(writeTimeout);
int writeResult = SSL_write(ssl, (const char *)buf, len); lastWriteCount = writeResult; returnValue = lastWriteCount >= len; if (writeResult < 0 && GetErrorCode(LastWriteError) == NoError) ConvertOSError(-1, LastWriteError); }
channelPointerMutex.EndRead();
return returnValue;}
PBoolean PSSLChannel::Close(){ PBoolean ok = SSL_shutdown(ssl); return PIndirectChannel::Close() && ok;}
PBoolean PSSLChannel::Accept(PChannel & channel){ if (Open(channel)) return ConvertOSError(SSL_accept(ssl)); return PFalse;}
PBoolean PSSLChannel::Accept(PChannel * channel, PBoolean autoDelete){ if (Open(channel, autoDelete)) return ConvertOSError(SSL_accept(ssl)); return PFalse;}
PBoolean PSSLChannel::Connect(){ if (IsOpen()) return ConvertOSError(SSL_connect(ssl)); return PFalse;}
PBoolean PSSLChannel::Connect(PChannel * channel, PBoolean autoDelete)
V-5
Universitas Sumatera Utara
{ if (Open(channel, autoDelete)) return ConvertOSError(SSL_connect(ssl)); return PFalse;}
PBoolean PSSLChannel::UseCertificate(const PSSLCertificate & certificate){ return SSL_use_certificate(ssl, certificate);}
void PSSLChannel::SetVerifyMode(VerifyMode mode){ int verify;
switch (mode) { default : case VerifyNone: verify = SSL_VERIFY_NONE; break;
case VerifyPeer: verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; break;
case VerifyPeerMandatory: verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; }
SSL_set_verify(ssl, verify, VerifyCallBack);}
PBoolean PSSLChannel::OnOpen(){ BIO * bio = BIO_new(&methods_Psock); if (bio == NULL) { SSLerr(SSL_F_SSL_SET_FD,ERR_R_BUF_LIB); return PFalse; }
// "Open" then bio bio->ptr = this; bio->init = 1;
SSL_set_bio(ssl, bio, bio); return PTrue;}
V-6
Universitas Sumatera Utara