OpenBSD-Firewall Packet Sceheduling Analysis for IP Telephony QoS [Part 2: Design and Simulation Implementation]
Friday, January 18, 2008 7:18:44 PM
[Technical Background]
Network:
NAT (Network Address Translation)
Network Address Translation is a technique of transceiving network traffic through a router that involves re-writing the source and/or destination IP addresses and usually also the TCP/UDP port numbers of IP packets as they pass through. Checksums (both IP and TCP/UDP) must also be rewritten to take account of the changes. Most systems using NAT do so in order to enable multiple hosts on a private network to access the Internet using a single public IP address. NAT first became popular as a way to deal with the IPv4 address shortage and to avoid all the difficulty of reserving IP addresses. NAT also adds to security as it disguises the internal network's structure: all traffic appears to outside parties as if it originates from the gateway machine.
In a typical configuration, a local network uses one of the designated "private" IP address subnets (the RFC 1918 Private Network Addresses are 192.168.x.x, 172.16.x.x through 172.31.x.x, and 10.x.x.x - using CIDR notation, 192.168/16, 172.16/12, and 10/8), and a router on that network has a private address (such as 192.168.0.1) in that address space. The router is also connected to the Internet with a single "public" address (known as "overloaded" NAT) or multiple "public" addresses assigned by an ISP. As traffic passes from the local network to the Internet, the source address in each packet is translated on the fly from the private addresses to the public address(es). The router tracks basic data about each active connection (particularly the destination address and port). When a reply returns to the router, it uses the connection tracking data it stored during the outbound phase to determine where on the internal network to forward the reply; the TCP or UDP client port numbers are used to demultiplex the packets in the case of overloaded NAT, or IP address and port number when multiple public addresses are available, on packet return. To a system on the Internet, the router itself appears to be the source/destination for this traffic.
Gateway
Every network segment has its own gateway to the world, the address where all packets not destined to hosts outside the same network segment are being sent to. It is a common mistake to confuse the gateway for the segment with the gateway for the Firewall. When we are configuring firewalls using designs where Open-BSD and pf are also routing packets the gateway address for local hosts behind pf is the local address of the machine that pf is running on, and the gateway address for the firewall is its external address.
The job of the gateway is to act as a translator between these two interfaces (internal and external interface) by passing packets back and forth between them. It connects the Internet with our internal network, making the two networks visible to one another. When an internal host contacts an external one on the Internet, the NAT gateway records the connection and translates the outgoing packets so they appear to be coming from itself. When the response comes in from the Internet over the external interface, the gateway recognizes it as being part of a valid connection and passes it to the internal interface to be sent to the proper host on the network.
Firewall
OpenBSD-Firewall PF is stateful packet filter firewall which included as Second Generation firewalls, it's do not simply examine the contents of each packet on an individual basis without regard to their placement within the packet series as their predecessors had done, rather they compare some key parts of the trusted database packets. This technology is generally referred to as a 'stateful firewall' as it maintains records of all connections passing through the firewall and is able to determine whether a packet is the start of a new connection or part of an existing connection. Though there is still a set of static rules in such a firewall, the state of a connection can in itself be one of the criteria which trigger specific rules. This feature can help prevent attacks which exploit existing connections, or certain Denial-of-service attacks.
Packet Filters or PF, operate at a relatively low level of the TCP/IP protocol stack, not allowing packets to pass through the firewall unless they match the established ruleset. The firewall administrator may define the rules; or default rules may apply. Stateful firewalls maintain context about active sessions, and use that "state information" to speed up packet processing. Any existing network connection can be described by several properties, including source and destination IP address, UDP or TCP ports, and the current stage of the connection's lifetime (including session initiation, handshaking, data transfer, or completion connection). If a packet does not match an existing connection, it will be evaluated according to the ruleset for new connections. If a packet matches an existing connection based on comparison with the firewall's state table, it will be allowed to pass without further processing.
VoIP Protocols and Codecs:
Call Signaling:
SIP
The Session Initiation Protocol (SIP) is an application-layer control (signaling) protocol for creating, modifying, and terminating sessions with one or more participants. It can be used to create two-party, multiparty, or multicast sessions that include Internet telephone calls, multimedia distribution, and multimedia conferences. SIP is designed to be independent of the underlying transport layer; it can run on TCP, UDP, or SCTP. SIP has two components: User Agents and SIP servers (including SIP proxies, SIP registrars, and SIP redirect servers). A user agent is a logical entity that acts as both a client and a server. A user agent client initiates a SIP transaction with a request. A user agent server responds to a SIP request by accepting, rejecting or redirecting the request. A SIP server is a server that accepts requests and sends responses back to those requests. SIP is a request-response protocol that closely resembles HTTP. A SIP request and the appropriate response are grouped into a SIP transactions, as defined in RFC 3261 (INVITE, ACK, OPTIONS, BYE, CANCEL, REGISTER) and RFC 3311 (UPDATE).
SIP is based on an HTTP-like request/response transaction model. Each transaction consists of a request that invokes a particular method, or function, on the server and at least one response. In this example, the transaction begins with Alice's softphone sending an INVITE request addressed to Bob's SIP URI. INVITE is an example of a SIP method that specifies the action that the requestor (Alice) wants the server (Bob) to take. The INVITE request contains a number of header fields. Header fields are named attributes that provide additional information about a message. The ones present in an INVITE include a unique identifier for the call, the destination address, Alice's address, and information about the type of session that Alice wishes to establish with Bob. The INVITE might look like this:
IAX
IAX(2) is a binary protocol and uses therefore the bandwidth efficient for voice, yet may not be as efficient for other media stream types (like video). It uses a single well-known port (4569) and sends both the signaling and media packets in the same channel. This has the big advantage of being Network Address Translation (NAT) friendly, and causing only few firewall problems.
In IAX2 lingo, packets are called "frames". A full frame has a 12-byte-header and is mostly related to connection control (NEW - ACCEPT - RINGING - ANSWER - HANGUP packets). Full frames require a receiver confirmation; every frame contain a 15-bit "call number" that allows an end station to multiplex connections; it also contains a 32-bit timestamp that expresses how many milliseconds have elapsed since the conversation started.4 Mini-frames have a
shorter header (4 bytes), and contain only a the lower 16 bits of the conversation timestamp. When this counter wraps, a full frame is used to synchronize the short timestamp. Connections can be trunked, meaning that packets belonging to multiple connections are sent in one meta trunk frame with 8 header bytes and 4 bytes header per call/packet. Again, this makes the protocol even more efficient,since the input-output overhead is very notable for small voice packet.
IAX2 also supports built-in support for encryption. It uses an AES (Advanced Encryption Standard) 128-bit block cipher.The protocol is built upon a "shared secret" type of setup.That is, before any calls can be encrypted, the "shared secret" must be stored on each Asterisk server. IAX2's AES 128-bit encryption works on a call-by-call basis and only the data portion of the message is encrypted.
Data Transport:
For transporting voice data in IP networks, the User Datagram Protocol (UPD) is used. On top of UDP, the Real Time Protocol (RTP) provides packet sequence information so endpoints can determine arrival order. RTCP (Real Time Control Protocol), RTP?s companion, sends feedback about the quality of the stream. RTSP (Real Time Streaming Protocol) is used for streaming prerecorded data, a possible application in VoIP is a user listening to his voice
messages or sending prerecorded conference calls. RTSP is the only protocol that can use a large buffer since this is a one-way stream; bi-directional communications are not buffered, unless for balancing out jitter (using a small
"dejitter buffer").
SIP works in concert with several other protocols and is only involved in the signalling portion of a communication session. SIP acts as a carrier for the Session Description Protocol (SDP), which describes the media content of the session, e.g. what IP ports to use, the codec being used etc. In typical use, SIP "sessions" are simply packet streams of the Real-time Transport Protocol (RTP). RTP is the carrier for the actual voice or video content itself.
IAX2 uses one UDP port for both signaling and media transfer.The default UDP port is 4569 and is used for both the destination port and the source port as well.This means signaling for call setup, tear down, and modification, along with the UDP datagrams, are all sent over the same port using a single protocol.This also means that IAX2 has its own built-in means of transferring voice data, so RTP is not used.
Codec:
When the "audio" data of a VoIP call is placed into an RTP packet, a codec (enCOder/DECoder) is used.This is the method of how the "audio" data is placed within the UDP datagram. Information about what codec to use is between the systems and is negotiated during the call setup (signaling).
Some codecs use compression, while others do not. Compressed codecs will be able to cram more data into the RTP packet, but there is always a trade-off.With compressed codecs, your CPU will work harder at cramming data into the UDP datagram.You'll also lose a bit of quality in the audio. However, less network bandwidth will be used to send the information.With noncompressed codecs, the audio data will be placed in the UDP datagram in a more "raw"-like form.This requires much less CPU time, but necessitates more network bandwidth.There's always a trade-off of CPU power versus bandwidth when using compressed and noncompressed codecs.
Packet Scheduling Algorithms:
PRIQ
The PRIQ scheduler uses a simple flat bandwidth division model, where you divide the bandwidth into smaller slices with different priority.It consist of multiple classes with static priorities. This is usually achieved either with each class having its own, usually a FIFO queue, or with a single sorted queue with higher priority packets added to the front or middle rather than to the end of the queue. A single queue solution can be implemented with e.g. a linked list or a hash table indexed by class arrival time. Incoming packets are classified to one of the classes. Outgoing packets are selected based on classes' priorities starting from highest and proceeding downwards. Higher priority class's queue gets emptied in full before moving to lower priority one. This makes it possible for a lower priority class to suffer from starvation if there is a continuous influx of packet to higher priority classes. In order to avoid starvation of critical traffic, such traffic must always be assigned to the highest priority class.
Priority Queueing
CBQ
The CBQ scheduler is a network router queueing method that allows traffic to share bandwidth equally, after being grouped by classes. The classes can be based upon a variety of parameters, such as priority, interface, or originating program. Class based Qeueuing (CBQ) is a classful scheduling algorithm where classes form a tree-like hierarchy. Starting from the root class each class can have zero or more children. Each child class has its own bandwidth allotment taken from the allotment of the parent class. This way the sum of bandwidth allocated amongst all the leaf classes can equal but cannot exceed the bandwidth available for the root class.
CBQ introduces a concept called "borrowing". "Borrowing" means that a class running out of its allocated bandwidth can use bandwidth allocated to some other class as long that class has not ran out of its allocated bandwidth. To control borrowing, CBQ has three special class attributes: bounded, isolated and exempt.
By default all classes can borrow bandwidth from their parents and siblings. Bounded classes are not allowed to borrow bandwidth from their parents or siblings. This means that bounded class can never transmit more traffic than its allocated bandwidth allows it to. Isolated classes behave like bounded classes and additionally do not borrow bandwidth to their siblings. This means that bandwidth assigned for an isolated class is usable only by that class and its children. Exempt classes are never restricted from borrowing bandwidth from other classes no matter what the bandwidth usage of the target class.
Tree-like structure of CBQ classes
HFSC
HFSC based on a service curve concept which define QoS requirement from a traffic class or a session at bandwidth and priority(delay) matter.
At this architecture, every class in hierarchy will be associated with a service curve. Ideal model Fair Service Curve takes :
a) Branch service for every class will be guaranteed simultantly.
b) Bandwidth exceeding which not be used by a class will be given to its neighbour class fairly.
HFSC model approach with:
- Solving conflict which happen in branch class requirement
- Minimalized difference between service for every class which must recieved ideally and service which recieved actually
A session i guaranteed by a service curve Si(t) if it suitable with this equation:
Si(t2-t1) =< Wi (t1,t2); t1<t2
or
S(t) => Z Si(t)
HFSC using non-linear service curve so that bandwidth and delay component will be separated. But with non-linear service curve it's no possible for guarantee service curve simultantly, so then HFSC using two criteria in packet voting, those are:
1. Realtime criteria for guarantee service curve at every branch class
2. Link-sharing criteria for guarantee service curve at interior class and distributing exceeding bandwidth fairly.
Therefore at every branch class has three components (ei, di, vi) which representing eligible time, deadline, and virtual time. And a class leaf just consist of one component that is virtual time vi.
OpenBSD-Firewall's views for HFSC rules:
The HFSC scheduler offers similar features to CBQ, but give more enhances scheduler with the ability to define two types of packet schedulers: real-time and link-share. When real-time scheduling isn't used or no packets can be scheduled using this algorithm, link-share takes over. When more bandwidth is available, queues will use it, unless we place a cap on the bandwidth. The HFSC behavior is controlled with these parameters:
a. realtime : controls the minimum bandwidth required for the queue. When more bandwidth is available, it will be used unless we use the upperlimit parameter. Packets are scheduled using the real-time scheduling algorithm first. When no packets are legible for real-time scheduling, or when we do not use real-time scheduling, HFSC will use
link-share packet scheduling.
b. linkshare : sets the minimum `share' of the parent queue bandwidth for the current queue. When more bandwidth is available, it will be used unless you use the upperlimit parameter. If we also use the realtime parameter, it will take precedence over linkshare.
c. upperlimit : set the maximum bandwidth allowed for the queue.Each of these parameters can be followed by a single numeric value that defines the amount of bandwidth that the queue can use, or it can be followed by a triple of service curve parameters that define: (a) the initial level of bandwidth (m1), (b) time delay (d, measured in milliseconds), and (c) the level to which bandwidth will be adjusted after that time (m2). These parameters define the so-called service curve, which can be convex or concave,with the exception of the realtime parameter, which must be convex. A concave service curve is created, when the m1 parameter is lower than m2. A convex curve is created when m1 is higher than m2. It is also possible to define a flat service curve when m1 is equal to m2. This can be replaced with a single value (m1 and d are omitted).
In one scenario two users share a single Internet connection with a 1000 kbit capacity; each user should have control of at least 500 kbit of that capacity at any given moment. One of the users (party A) uses a maximum of 100 kbit of his bandwidth for Internet telephony and the remainder of the transmission capacity for general data transport. Figure below shows the corresponding hierarchy.
Hierarchy of shared network access
Softswitch Server and Softphone Client:
Asterisk:
Asterisk is an open source/free software implementation of a telephone private branch exchange (PBX) A PBX is a piece of equipment that handles telephone switching owned by a private business, rather than a telephone company. PBXes were for medium-to-large businesses that would create a lot of telephone traffic starting from, and terminating
within, the same location. Rather than having that traffic tie up the switch that handles telephones for the rest of the area, PBXes were designed to be small switches to handle this traffic.Thus, the PBX would keep the internal traffic internal, and also handle telephone calls to and from the rest of the telephone network.
Xlite:
SIP based softphone for VoIP, running at Windows, Linux, and Mac.
KIAX:
IAX based softphone for VoIP, running at Linux on KDE window manager.
[Network Design]
The network design for simulation:
Scheme's explanation:
The network scheme above is network scheme where the simulation will be execute.That network consist of two network service clients, a firewal which have another function as NAT-Gateway, and a server for VoIP and HTTP service provider. Server behind firewall have a private address which will be NAT-ed at NAT-Gateway. Firewall will be redirect some service especially for VoIP and web service. Client have public address and will be interact with Server to request VoIP and Web service.
[Implementation]
Implementation and Configuration
a. Softswitch Server:
Asterisk's IP Address: 172.16.17.2
Asterisk Configuration:
1. Configuration for two SIP clients at file /etc/asterisk/sip.conf:
2. Configuration for IAX clients at file /etc/asterisk/iax.conf :
[/CODE]
-------- cut --------
;; Data Account
[8111]
type=friend
context=default
username=8111
secret=1234
host=dynamic
allow=all
nat=yes
;nat=no
[8112]
type=friend
context=default
username=8112
secret=1234
host=dynamic
allow=all
nat=yes
;nat=no
------- end ------
[/CODE]
3. Configuration for dial plan at file /etc/asterisk/extensions.conf :
4. Configuration for SIP NAT at file /etc/asterisk/sip_nat.conf :
5. Configuration for RTP port at file /etc/asterisk/rtp.conf :
Softphone Client :
Both at Xlite and KIAX, at general we will setting server address (10.14.15.26), account (username variable), and password (secret variable)
.
b. NAT-Gateway:
1. Configuration at /etc/rc.conf.local :
2. Configuration at /etc/sysctl.conf :
3. Configuration at /etc/pfstat.conf :
4. Configuration for crontab :
OpenBSD-Firewall PF rules :
Packet Schedulling rules for simulation scenarios:
CBQ:
PRIQ :
HFSC :
[Simulation]
Simulation consist of three parts, every part for one kind of packet scheduling algorithm. The scenario run like this:
At Firewall-NAT Gateway:
1. Change PF rules due to packet scheduling test scenario : # pfctl -f /etc/pfrules
2. At the end of every test, user running this command : pfstat -q -p -c /etc/pfstat.conf -d /var/log/pfstat
At Server:
1. Running http server daemon.
2. Running Asterisk server.
3. Running voip packet generator's script for server mode, the script code:
At Client :
1. User running browser and accesing the web server
2. User running softphone client and try making connection
3. User running voip packet generator's script for client mode, the script code:
That script running via console with this command: ./voip-gen-client.pl --size 160 --pps 50 --time 307 --streams 57 --port 4569 -host 10.14.15.26
Network:
NAT (Network Address Translation)
Network Address Translation is a technique of transceiving network traffic through a router that involves re-writing the source and/or destination IP addresses and usually also the TCP/UDP port numbers of IP packets as they pass through. Checksums (both IP and TCP/UDP) must also be rewritten to take account of the changes. Most systems using NAT do so in order to enable multiple hosts on a private network to access the Internet using a single public IP address. NAT first became popular as a way to deal with the IPv4 address shortage and to avoid all the difficulty of reserving IP addresses. NAT also adds to security as it disguises the internal network's structure: all traffic appears to outside parties as if it originates from the gateway machine.
In a typical configuration, a local network uses one of the designated "private" IP address subnets (the RFC 1918 Private Network Addresses are 192.168.x.x, 172.16.x.x through 172.31.x.x, and 10.x.x.x - using CIDR notation, 192.168/16, 172.16/12, and 10/8), and a router on that network has a private address (such as 192.168.0.1) in that address space. The router is also connected to the Internet with a single "public" address (known as "overloaded" NAT) or multiple "public" addresses assigned by an ISP. As traffic passes from the local network to the Internet, the source address in each packet is translated on the fly from the private addresses to the public address(es). The router tracks basic data about each active connection (particularly the destination address and port). When a reply returns to the router, it uses the connection tracking data it stored during the outbound phase to determine where on the internal network to forward the reply; the TCP or UDP client port numbers are used to demultiplex the packets in the case of overloaded NAT, or IP address and port number when multiple public addresses are available, on packet return. To a system on the Internet, the router itself appears to be the source/destination for this traffic.
Gateway
Every network segment has its own gateway to the world, the address where all packets not destined to hosts outside the same network segment are being sent to. It is a common mistake to confuse the gateway for the segment with the gateway for the Firewall. When we are configuring firewalls using designs where Open-BSD and pf are also routing packets the gateway address for local hosts behind pf is the local address of the machine that pf is running on, and the gateway address for the firewall is its external address.
The job of the gateway is to act as a translator between these two interfaces (internal and external interface) by passing packets back and forth between them. It connects the Internet with our internal network, making the two networks visible to one another. When an internal host contacts an external one on the Internet, the NAT gateway records the connection and translates the outgoing packets so they appear to be coming from itself. When the response comes in from the Internet over the external interface, the gateway recognizes it as being part of a valid connection and passes it to the internal interface to be sent to the proper host on the network.
Firewall
OpenBSD-Firewall PF is stateful packet filter firewall which included as Second Generation firewalls, it's do not simply examine the contents of each packet on an individual basis without regard to their placement within the packet series as their predecessors had done, rather they compare some key parts of the trusted database packets. This technology is generally referred to as a 'stateful firewall' as it maintains records of all connections passing through the firewall and is able to determine whether a packet is the start of a new connection or part of an existing connection. Though there is still a set of static rules in such a firewall, the state of a connection can in itself be one of the criteria which trigger specific rules. This feature can help prevent attacks which exploit existing connections, or certain Denial-of-service attacks.
Packet Filters or PF, operate at a relatively low level of the TCP/IP protocol stack, not allowing packets to pass through the firewall unless they match the established ruleset. The firewall administrator may define the rules; or default rules may apply. Stateful firewalls maintain context about active sessions, and use that "state information" to speed up packet processing. Any existing network connection can be described by several properties, including source and destination IP address, UDP or TCP ports, and the current stage of the connection's lifetime (including session initiation, handshaking, data transfer, or completion connection). If a packet does not match an existing connection, it will be evaluated according to the ruleset for new connections. If a packet matches an existing connection based on comparison with the firewall's state table, it will be allowed to pass without further processing.
VoIP Protocols and Codecs:
Call Signaling:
SIP
The Session Initiation Protocol (SIP) is an application-layer control (signaling) protocol for creating, modifying, and terminating sessions with one or more participants. It can be used to create two-party, multiparty, or multicast sessions that include Internet telephone calls, multimedia distribution, and multimedia conferences. SIP is designed to be independent of the underlying transport layer; it can run on TCP, UDP, or SCTP. SIP has two components: User Agents and SIP servers (including SIP proxies, SIP registrars, and SIP redirect servers). A user agent is a logical entity that acts as both a client and a server. A user agent client initiates a SIP transaction with a request. A user agent server responds to a SIP request by accepting, rejecting or redirecting the request. A SIP server is a server that accepts requests and sends responses back to those requests. SIP is a request-response protocol that closely resembles HTTP. A SIP request and the appropriate response are grouped into a SIP transactions, as defined in RFC 3261 (INVITE, ACK, OPTIONS, BYE, CANCEL, REGISTER) and RFC 3311 (UPDATE).
SIP is based on an HTTP-like request/response transaction model. Each transaction consists of a request that invokes a particular method, or function, on the server and at least one response. In this example, the transaction begins with Alice's softphone sending an INVITE request addressed to Bob's SIP URI. INVITE is an example of a SIP method that specifies the action that the requestor (Alice) wants the server (Bob) to take. The INVITE request contains a number of header fields. Header fields are named attributes that provide additional information about a message. The ones present in an INVITE include a unique identifier for the call, the destination address, Alice's address, and information about the type of session that Alice wishes to establish with Bob. The INVITE might look like this:
atlanta.com . . . biloxi.com
. proxy proxy .
. .
Alice's . . . . . . . . . . . . . . . . . . . . Bob's
softphone SIP Phone
| | | |
| INVITE F1 | | |
|--------------->| INVITE F2 | |
| 100 Trying F3 |--------------->| INVITE F4 |
|<---------------| 100 Trying F5 |--------------->|
| |<-------------- | 180 Ringing F6 |
| | 180 Ringing F7 |<---------------|
| 180 Ringing F8 |<---------------| 200 OK F9 |
|<---------------| 200 OK F10 |<---------------|
| 200 OK F11 |<---------------| |
|<---------------| | |
| ACK F12 |
|------------------------------------------------->|
| Media Session |
|<================================================>|
| BYE F13 |
|<-------------------------------------------------|
| 200 OK F14 |
|------------------------------------------------->|
| |
SIP session setup example with SIP trapezoid
INVITE sip:bob@biloxi.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob <sip:bob@biloxi.com>
From: Alice <sip:alice@atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:alice@pc33.atlanta.com>
Content-Type: application/sdp
Content-Length: 142
(Alice's SDP not shown)
IAX
IAX(2) is a binary protocol and uses therefore the bandwidth efficient for voice, yet may not be as efficient for other media stream types (like video). It uses a single well-known port (4569) and sends both the signaling and media packets in the same channel. This has the big advantage of being Network Address Translation (NAT) friendly, and causing only few firewall problems.
In IAX2 lingo, packets are called "frames". A full frame has a 12-byte-header and is mostly related to connection control (NEW - ACCEPT - RINGING - ANSWER - HANGUP packets). Full frames require a receiver confirmation; every frame contain a 15-bit "call number" that allows an end station to multiplex connections; it also contains a 32-bit timestamp that expresses how many milliseconds have elapsed since the conversation started.4 Mini-frames have a
shorter header (4 bytes), and contain only a the lower 16 bits of the conversation timestamp. When this counter wraps, a full frame is used to synchronize the short timestamp. Connections can be trunked, meaning that packets belonging to multiple connections are sent in one meta trunk frame with 8 header bytes and 4 bytes header per call/packet. Again, this makes the protocol even more efficient,since the input-output overhead is very notable for small voice packet.
IAX2 also supports built-in support for encryption. It uses an AES (Advanced Encryption Standard) 128-bit block cipher.The protocol is built upon a "shared secret" type of setup.That is, before any calls can be encrypted, the "shared secret" must be stored on each Asterisk server. IAX2's AES 128-bit encryption works on a call-by-call basis and only the data portion of the message is encrypted.
Data Transport:
For transporting voice data in IP networks, the User Datagram Protocol (UPD) is used. On top of UDP, the Real Time Protocol (RTP) provides packet sequence information so endpoints can determine arrival order. RTCP (Real Time Control Protocol), RTP?s companion, sends feedback about the quality of the stream. RTSP (Real Time Streaming Protocol) is used for streaming prerecorded data, a possible application in VoIP is a user listening to his voice
messages or sending prerecorded conference calls. RTSP is the only protocol that can use a large buffer since this is a one-way stream; bi-directional communications are not buffered, unless for balancing out jitter (using a small
"dejitter buffer").
SIP works in concert with several other protocols and is only involved in the signalling portion of a communication session. SIP acts as a carrier for the Session Description Protocol (SDP), which describes the media content of the session, e.g. what IP ports to use, the codec being used etc. In typical use, SIP "sessions" are simply packet streams of the Real-time Transport Protocol (RTP). RTP is the carrier for the actual voice or video content itself.
IAX2 uses one UDP port for both signaling and media transfer.The default UDP port is 4569 and is used for both the destination port and the source port as well.This means signaling for call setup, tear down, and modification, along with the UDP datagrams, are all sent over the same port using a single protocol.This also means that IAX2 has its own built-in means of transferring voice data, so RTP is not used.
Codec:
When the "audio" data of a VoIP call is placed into an RTP packet, a codec (enCOder/DECoder) is used.This is the method of how the "audio" data is placed within the UDP datagram. Information about what codec to use is between the systems and is negotiated during the call setup (signaling).
Some codecs use compression, while others do not. Compressed codecs will be able to cram more data into the RTP packet, but there is always a trade-off.With compressed codecs, your CPU will work harder at cramming data into the UDP datagram.You'll also lose a bit of quality in the audio. However, less network bandwidth will be used to send the information.With noncompressed codecs, the audio data will be placed in the UDP datagram in a more "raw"-like form.This requires much less CPU time, but necessitates more network bandwidth.There's always a trade-off of CPU power versus bandwidth when using compressed and noncompressed codecs.
Codec | Payloads(bytes) | pps ======================================== G.711 | 160 | 50 G.726 (ADPCM32) | 80 | 50 GSM (slow mode) | 66 | 25 GSM (fast mode) | 33 | 50 ----------------------------------------
Packet Scheduling Algorithms:
PRIQ
The PRIQ scheduler uses a simple flat bandwidth division model, where you divide the bandwidth into smaller slices with different priority.It consist of multiple classes with static priorities. This is usually achieved either with each class having its own, usually a FIFO queue, or with a single sorted queue with higher priority packets added to the front or middle rather than to the end of the queue. A single queue solution can be implemented with e.g. a linked list or a hash table indexed by class arrival time. Incoming packets are classified to one of the classes. Outgoing packets are selected based on classes' priorities starting from highest and proceeding downwards. Higher priority class's queue gets emptied in full before moving to lower priority one. This makes it possible for a lower priority class to suffer from starvation if there is a continuous influx of packet to higher priority classes. In order to avoid starvation of critical traffic, such traffic must always be assigned to the highest priority class.
Priority Queueing
CBQ
The CBQ scheduler is a network router queueing method that allows traffic to share bandwidth equally, after being grouped by classes. The classes can be based upon a variety of parameters, such as priority, interface, or originating program. Class based Qeueuing (CBQ) is a classful scheduling algorithm where classes form a tree-like hierarchy. Starting from the root class each class can have zero or more children. Each child class has its own bandwidth allotment taken from the allotment of the parent class. This way the sum of bandwidth allocated amongst all the leaf classes can equal but cannot exceed the bandwidth available for the root class.
CBQ introduces a concept called "borrowing". "Borrowing" means that a class running out of its allocated bandwidth can use bandwidth allocated to some other class as long that class has not ran out of its allocated bandwidth. To control borrowing, CBQ has three special class attributes: bounded, isolated and exempt.
By default all classes can borrow bandwidth from their parents and siblings. Bounded classes are not allowed to borrow bandwidth from their parents or siblings. This means that bounded class can never transmit more traffic than its allocated bandwidth allows it to. Isolated classes behave like bounded classes and additionally do not borrow bandwidth to their siblings. This means that bandwidth assigned for an isolated class is usable only by that class and its children. Exempt classes are never restricted from borrowing bandwidth from other classes no matter what the bandwidth usage of the target class.
Tree-like structure of CBQ classes
HFSC
HFSC based on a service curve concept which define QoS requirement from a traffic class or a session at bandwidth and priority(delay) matter.
At this architecture, every class in hierarchy will be associated with a service curve. Ideal model Fair Service Curve takes :
a) Branch service for every class will be guaranteed simultantly.
b) Bandwidth exceeding which not be used by a class will be given to its neighbour class fairly.
HFSC model approach with:
- Solving conflict which happen in branch class requirement
- Minimalized difference between service for every class which must recieved ideally and service which recieved actually
A session i guaranteed by a service curve Si(t) if it suitable with this equation:
Si(t2-t1) =< Wi (t1,t2); t1<t2
or
S(t) => Z Si(t)
HFSC using non-linear service curve so that bandwidth and delay component will be separated. But with non-linear service curve it's no possible for guarantee service curve simultantly, so then HFSC using two criteria in packet voting, those are:
1. Realtime criteria for guarantee service curve at every branch class
2. Link-sharing criteria for guarantee service curve at interior class and distributing exceeding bandwidth fairly.
Therefore at every branch class has three components (ei, di, vi) which representing eligible time, deadline, and virtual time. And a class leaf just consist of one component that is virtual time vi.
OpenBSD-Firewall's views for HFSC rules:
The HFSC scheduler offers similar features to CBQ, but give more enhances scheduler with the ability to define two types of packet schedulers: real-time and link-share. When real-time scheduling isn't used or no packets can be scheduled using this algorithm, link-share takes over. When more bandwidth is available, queues will use it, unless we place a cap on the bandwidth. The HFSC behavior is controlled with these parameters:
a. realtime : controls the minimum bandwidth required for the queue. When more bandwidth is available, it will be used unless we use the upperlimit parameter. Packets are scheduled using the real-time scheduling algorithm first. When no packets are legible for real-time scheduling, or when we do not use real-time scheduling, HFSC will use
link-share packet scheduling.
b. linkshare : sets the minimum `share' of the parent queue bandwidth for the current queue. When more bandwidth is available, it will be used unless you use the upperlimit parameter. If we also use the realtime parameter, it will take precedence over linkshare.
c. upperlimit : set the maximum bandwidth allowed for the queue.Each of these parameters can be followed by a single numeric value that defines the amount of bandwidth that the queue can use, or it can be followed by a triple of service curve parameters that define: (a) the initial level of bandwidth (m1), (b) time delay (d, measured in milliseconds), and (c) the level to which bandwidth will be adjusted after that time (m2). These parameters define the so-called service curve, which can be convex or concave,with the exception of the realtime parameter, which must be convex. A concave service curve is created, when the m1 parameter is lower than m2. A convex curve is created when m1 is higher than m2. It is also possible to define a flat service curve when m1 is equal to m2. This can be replaced with a single value (m1 and d are omitted).
In one scenario two users share a single Internet connection with a 1000 kbit capacity; each user should have control of at least 500 kbit of that capacity at any given moment. One of the users (party A) uses a maximum of 100 kbit of his bandwidth for Internet telephony and the remainder of the transmission capacity for general data transport. Figure below shows the corresponding hierarchy.
Hierarchy of shared network access
Softswitch Server and Softphone Client:
Asterisk:
Asterisk is an open source/free software implementation of a telephone private branch exchange (PBX) A PBX is a piece of equipment that handles telephone switching owned by a private business, rather than a telephone company. PBXes were for medium-to-large businesses that would create a lot of telephone traffic starting from, and terminating
within, the same location. Rather than having that traffic tie up the switch that handles telephones for the rest of the area, PBXes were designed to be small switches to handle this traffic.Thus, the PBX would keep the internal traffic internal, and also handle telephone calls to and from the rest of the telephone network.
Xlite:
SIP based softphone for VoIP, running at Windows, Linux, and Mac.
KIAX:
IAX based softphone for VoIP, running at Linux on KDE window manager.
[Network Design]
The network design for simulation:
Scheme's explanation:
The network scheme above is network scheme where the simulation will be execute.That network consist of two network service clients, a firewal which have another function as NAT-Gateway, and a server for VoIP and HTTP service provider. Server behind firewall have a private address which will be NAT-ed at NAT-Gateway. Firewall will be redirect some service especially for VoIP and web service. Client have public address and will be interact with Server to request VoIP and Web service.
[Implementation]
Implementation and Configuration
a. Softswitch Server:
Asterisk's IP Address: 172.16.17.2
Asterisk Configuration:
1. Configuration for two SIP clients at file /etc/asterisk/sip.conf:
------- cut --------- ;; Data Account [9111] type=friend context=default username=9111 secret=1234 host=dynamic allow=all nat=yes ;nat=no [9112] type=friend context=default username=9112 secret=1234 host=dynamic allow=all nat=yes ;nat=no #include sip_nat.conf ------ end --------
2. Configuration for IAX clients at file /etc/asterisk/iax.conf :
[/CODE]
-------- cut --------
;; Data Account
[8111]
type=friend
context=default
username=8111
secret=1234
host=dynamic
allow=all
nat=yes
;nat=no
[8112]
type=friend
context=default
username=8112
secret=1234
host=dynamic
allow=all
nat=yes
;nat=no
------- end ------
[/CODE]
3. Configuration for dial plan at file /etc/asterisk/extensions.conf :
------- cut ------
include => scenario_testing
[scenario_testing]
; panggilan SIP
exten => _9X.,1,Ringing
exten => _9X.,n,Wait,2
exten => _9X.,n,Dial(SIP/${EXTEN}|30)
exten => _9X.,n,Hangup
; panggilan IAX
exten => _8X.,1,Ringing
exten => _8X.,n,Wait,3
exten => _8X.,n,Dial(IAX2/${EXTEN}|30)
exten => _8X.,n,Hangup
------- end ------
4. Configuration for SIP NAT at file /etc/asterisk/sip_nat.conf :
--------- begin -------- [general] port = 5060 bindaddr = 172.16.17.2 ; local address nat = yes canreinvite = no externip = 10.14.15.26 localnet = 172.16.17.2/255.255.255.0 qualify = yes ------- end ---------
5. Configuration for RTP port at file /etc/asterisk/rtp.conf :
------ cut ------ rtpstart=10000 rtpend=20000 ------ end ------
Softphone Client :
Both at Xlite and KIAX, at general we will setting server address (10.14.15.26), account (username variable), and password (secret variable)
.
b. NAT-Gateway:
1. Configuration at /etc/rc.conf.local :
----- begin ---- sendmail_flags=NO pf=YES pf_rules=/etc/pf.conf_std routed_flags=YES route add -net 10.14.0.0/16 10.14.15.26 ----- end ----
2. Configuration at /etc/sysctl.conf :
------ begin ----- net.inet.ip.forwarding=1 # 1=Permit forwarding (routing) of IPv4 packets ------ end ------
3. Configuration at /etc/pfstat.conf :
-------------- cut ------------------
collect 1 = interface "rl0" pass bytes in ipv4 diff
collect 2 = interface "rl0" pass bytes out ipv4 diff
collect 3 = global states entries
image "/home/shaeqe/hasil/pfstat.jpg" {
from 3 minutes to now
width 980 height 300
left
graph 1 bps "in" "bits/s" color 0 192 0 filled,
graph 2 bps "out" "bits/s" color 0 0 255
right
graph 3 "states" "entries" color 192 192 0
}
collect 4 = interface "rl0" pass packets in ipv4 diff
collect 5 = interface "rl0" pass packets out ipv4 diff
collect 6 = interface "rl0" block packets in ipv4 diff
collect 7 = interface "rl0" block packets out ipv4 diff
image "/home/shaeqe/hasil/pfstat-packets.jpg" {
from 5 minutes to now
width 980 height 300
left
graph 4 "pass in" "packets/s" color 0 192 0 filled,
graph 5 "pass out" "packets/s" color 0 0 255
right
graph 6 "block in" "packets/s" color 255 0 0,
graph 7 "block out" "packets/s" color 192 192 0
}
collect 8 = global states inserts diff
collect 9 = global states removals diff
collect 10 = global states searches diff
image "/home/shaeqe/hasil/pfstat-states.jpg" {
from 5 minutes to now
width 980 height 300
left
graph 8 "inserts" "states/s" color 0 192 0 filled,
graph 9 "removals" "states/s" color 0 0 255
right
graph 10 "searches" "states/s" color 255 0 0
}
collect 11 = queue "voip_traffic" pass bytes diff
collect 12 = queue "ssh_traffic" pass bytes diff
collect 13 = queue "www_traffic" pass bytes diff
collect 14 = queue "others" pass bytes diff
image "/home/shaeqe/hasil/pfstat-queues.jpg" {
from 5 minutes to now
width 980 height 300
left
graph 11 bps "voip" "bits/s" color 255 0 0,
graph 12 bps "ssh" "bits/s" color 192 192 0,
graph 13 bps "www" "bits/s" color 0 192 0,
graph 14 bps "others" "bits/s" color 0 0 255
}
collect 15 = global counters match diff
collect 16 = global counters bad-offset diff
collect 17 = global counters fragment diff
collect 18 = global counters short diff
collect 19 = global counters normalize diff
collect 20 = global counters memory diff
collect 21 = global counters bad-timestamp diff
collect 22 = global counters congestion diff
collect 23 = global counters ip-option diff
collect 24 = global counters proto-cksum diff
collect 25 = global counters state-mismatch diff
collect 26 = global counters state-insert diff
collect 27 = global counters state-limit diff
collect 28 = global counters src-limit diff
collect 29 = global counters synproxy diff
image "/home/shaeqe/hasil/pfstat-errors.jpg" {
from 5 minutes to now
width 980 height 300
left
graph 17 "frag" "/s" color 192 0 192,
graph 22 "cong" "/s" color 0 192 192,
graph 23 "iopt" "/s" color 0 0 255,
graph 24 "csum" "/s" color 192 192 0,
graph 25 "mism" "/s" color 255 0 0
# others are usually all zero here
right
graph 15 "match" "/s" color 0 192 0
}
------ end ------
4. Configuration for crontab :
--- cut ---- * * * * * /usr/local/bin/pfstat -q >> /var/log/pfstat 1 1 * * 1 tail -n 50000 /var/log/pfstat > /tmp/pfstat && mv /tmp/pfstat /var/log/pfstat --- end ----
OpenBSD-Firewall PF rules :
Packet Schedulling rules for simulation scenarios:
CBQ:
-------- begin ------
# $ Analisa Performansi Trafik VoIP terhadap QoS OpenBSD-Firewall $
# PF Rules by CBQ2
#
### MACROS ###
# Interfaces
ext_if="rl0"
int_if="rl1"
# IPs
web_srv="172.16.17.2"
ssh_srv="172.16.17.2"
voip_srv="172.16.17.2"
# Ports
web_ports="{www, https}"
ssh_ports="{22,3210}"
other_ssh_port="3210"
voip_tcp_port="5060"
voip_udp_ports="4569"
other_ports="{2000, 4520}"
# Service
icmp_allow="echoreq"
### OPTIONS ###
set block-policy drop
set optimization aggressive
set skip on lo0
set loginterface rl0
#set loginterface rl1
### SCRUB ###
scrub in all fragment reassemble
### QUALITY OF SERVICE ###
## Queue Rule ##
# Parent Rule For queueing on the external interface
altq on $ext_if cbq bandwidth 100% queue { voip_srvr_out, others_out }
#Child queue definition
queue voip_srvr_out bandwidth 89% priority 7 cbq(red borrow) { voip_traffic_out, ssh_traffic_out, www_traffic_out }
queue voip_traffic_out bandwidth 90% priority 6 cbq(red borrow)
queue ssh_traffic_out bandwidth 5% priority 4 cbq(red borrow)
queue www_traffic_out bandwidth 5% priority 3 cbq(red borrow)
queue others_out bandwidth 1% priority 3 cbq(default)
# Parent Rule For queueing on the internal interface
altq on $int_if cbq bandwidth 100% queue { voip_srvr_in, others_in }
#Child queue definition
queue voip_srvr_in bandwidth 89% priority 7 cbq(red borrow) { voip_traffic_in, ssh_traffic_in, www_traffic_in }
queue voip_traffic_in bandwidth 90% priority 6 cbq(red borrow)
queue ssh_traffic_in bandwidth 5% priority 4 cbq(red borrow)
queue www_traffic_in bandwidth 5% priority 3 cbq(red borrow)
queue others_in bandwidth 1% priority 3 cbq(default)
### PACKET REDIRECTION ###
# Outgoing
nat on $ext_if inet proto {tcp, udp} from $voip_srv to any port $other_ports -> $ext_if static-port
nat on $ext_if inet proto {tcp, udp} from $voip_srv to any port $voip_udp_ports -> $ext_if static-port
nat on $ext_if from $int_if:network to any -> $ext_if
# Incoming
rdr on $ext_if inet proto udp from any to any port $voip_udp_ports -> $voip_srv port $voip_udp_ports
rdr on $ext_if inet proto {tcp, udp} from any to any port $other_ports -> $voip_srv
rdr on $ext_if inet proto tcp from any to $ext_if port $web_ports -> $web_srv
rdr on $ext_if inet proto tcp from any to $ext_if port ssh -> $ssh_srv port ssh
rdr on $ext_if inet proto tcp from any to $ext_if port $other_ssh_port -> $ext_if
### FILTER PACKETS ###
# Basic
block log all
#pass all
pass quick on lo0 all
pass out log (all) quick on $ext_if from $ext_if to any flags S/SA keep state
pass in log (all) quick on $int_if from $web_srv to any flags S/SA keep state
# Web Server
pass in on $ext_if inet proto tcp from any to $web_srv port $web_ports flags S/SA synproxy state
pass out on $int_if inet proto tcp from any to $web_srv port $web_ports flags S/SA keep state
# ICMP
pass in inet proto icmp all icmp-type $icmp_allow keep state
pass out inet proto icmp all keep state
# SSH
pass in quick on $ext_if inet proto tcp from any to $ssh_srv port = ssh flags S/SAFR modulate state
pass out quick on $int_if inet proto tcp from any to $ssh_srv port = ssh flags S/SAFR modulate state
pass out quick on $ext_if inet proto tcp all flags S/SAFR modulate state
pass in quick on $ext_if inet proto tcp from any to $ext_if port $ssh_ports flags S/SA synproxy state
# VoIP
pass in log (all) quick on $ext_if proto {tcp, udp} from any port {$voip_udp_ports, $voip_tcp_port} to any port {$voip_udp_ports, $voip_tcp_port} flags S/SAFR keep state
pass out log (all) quick on $ext_if proto {tcp, udp} from any port {$voip_udp_ports, $voip_tcp_port} to any port {$voip_udp_ports, $voip_tcp_port} flags S/SAFR keep state
pass in log (all) quick on $ext_if proto {tcp, udp} from any port $other_ports to any port $other_ports flags S/SAFR keep state
pass out log (all) quick on $ext_if proto {tcp, udp} from any port $other_ports to any port $other_ports flags S/SAFR keep state
## Assigned to Queue Outbound
# VoIP
pass in log (all) quick on $ext_if proto {tcp, udp} from any to any port {$voip_udp_ports, $voip_tcp_port} keep state queue voip_traffic_out
pass out log (all) quick on $ext_if proto {tcp, udp} from any to any port {$voip_udp_ports, $voip_tcp_port} keep state queue voip_traffic_out
# Other
pass out log quick on $ext_if inet proto tcp from $ext_if to any port $ssh_ports flags S/SA synproxy state queue ssh_traffic_out
pass out log quick on $ext_if inet proto {tcp, udp} from $ext_if to any port $web_ports flags S/SA keep state queue www_traffic_out
pass out log quick on $ext_if inet proto {tcp, udp} from $ext_if to any port $other_ports flags S/SA keep state queue others_out
## Assigned to Queue Inbound
# VoIP
pass in log (all) quick on $int_if proto {tcp, udp} from any to any port {$voip_udp_ports, $voip_tcp_port} keep state queue voip_traffic_in
pass out log (all) quick on $int_if proto {tcp, udp} from any to any port {$voip_udp_ports, $voip_tcp_port} keep state queue voip_traffic_in
# Other
pass out log quick on $int_if inet proto tcp from $ext_if to any port $ssh_ports flags S/SA synproxy state queue ssh_traffic_in
pass out log quick on $int_if inet proto {tcp, udp} from $ext_if to any port $web_ports flags S/SA keep state queue www_traffic_in
pass out log quick on $int_if inet proto {tcp, udp} from $ext_if to any port $other_ports flags S/SA keep state queue others_in
-------- end -------
PRIQ :
------ begin ------
# $ Analisa Performansi Trafik VoIP terhadap QoS OpenBSD Firewall $
# PF Rules for PRIQ
#
### MACROS ###
# Interfaces
ext_if="rl0"
int_if="rl1"
# IPs
web_srv="172.16.17.2"
ssh_srv="172.16.17.2"
voip_srv="172.16.17.2"
# Ports
web_ports="{www, https}"
ssh_ports="{22, 3210}"
other_ssh_port="3210"
voip_tcp_port="5060"
voip_udp_port="4569"
other_ports="{2000, 4520}"
# Service
icmp_allow="echoreq"
### OPTIONS ###
set block-policy drop
set optimization aggressive
set skip on lo0
set loginterface rl0
set loginterface rl1
### SCRUB ###
scrub in all fragment reassemble
### QUALITY OF SERVICE ###
## Queue Rule ##
# Parent rule for queueing on the external interface
altq on $ext_if priq bandwidth 10Mb queue {voip_out, ssh_out, www_out, others_out}
# Child Rules
queue voip_out priority 15 priq(ecn)
queue ssh_out priority 12 priq(red)
queue www_out priority 11 priq(red)
queue others_out priority 7 priq(default)
# Parent rule for queueing on the internal interface
altq on $int_if priq bandwidth 10Mb queue {voip_in, ssh_in, www_in, others_in}
# Child Rules
queue voip_in priority 15 priq(ecn)
queue ssh_in priority 12 priq(red)
queue www_in priority 11 priq(red)
queue others_in priority 7 priq(default)
### PACKET REDIRECTION ###
# Outgoing
nat on $ext_if inet proto {tcp, udp} from $voip_srv to any port $other_ports -> $ext_if static-port
nat on $ext_if inet proto {tcp, udp} from $voip_srv to any port {$voip_tcp_port, $voip_udp_port} -> $ext_if static-port
nat on $ext_if from $int_if:network to any -> $ext_if
# Incoming
rdr on $ext_if inet proto {tcp, udp} from any to any port $voip_udp_port -> $voip_srv port $voip_udp_port
rdr on $ext_if inet proto tcp from any to $ext_if port $web_ports -> $web_srv
rdr on $ext_if inet proto tcp from any to $ext_if port ssh -> $ssh_srv port ssh
rdr on $ext_if inet proto tcp from any to $ext_if port $other_ssh_port -> $ext_if
### FILTER PACKETS ###
# Basic
block log all
# Pass rules
pass quick on lo0 all
pass out log (all) quick on $ext_if from $ext_if to any flags S/SA modulate state
pass in log (all) quick on $int_if from $web_srv to any flags S/SA
# Web Server
pass in on $ext_if inet proto tcp from any to $web_srv port $web_ports flags S/SA synproxy state
pass out on $int_if inet proto tcp from any to $web_srv port $web_ports flags S/SA keep state
# ICMP
pass in inet proto icmp all icmp-type $icmp_allow keep state
pass out inet proto icmp all keep state
# SSH
pass in quick on $ext_if inet proto tcp from any to $ssh_srv port = ssh flags S/SAFR modulate state
pass out quick on $int_if inet proto tcp from any to $ssh_srv port = ssh flags S/SAFR modulate state
pass out quick on $ext_if inet proto tcp all flags S/SAFR modulate state
pass in quick on $ext_if inet proto tcp from any to $ext_if port $ssh_ports flags S/SA synproxy state
# VoIP
pass in log (all) quick on $ext_if proto {tcp, udp} from any port {$voip_udp_port, $voip_tcp_port} to any port { $voip_udp_port, $voip_tcp_port } flags S/SAFR keep state
pass out log (all) quick on $ext_if proto {tcp, udp} from any port {$voip_udp_port, $voip_tcp_port} to any port { $voip_udp_port, $voip_tcp_port } flags S/SAFR keep state
pass in log (all) quick on $ext_if proto {tcp, udp} from any port $other_ports to any port $other_ports flags S/SAFR keep state
pass out log (all) quick on $ext_if proto {tcp, udp} from any port $other_ports to any port $other_ports flags S/SAFR keep state
## Assigned to Queue outbound
# VoIP
#pass in from any to $voip_srv
pass in log (all) quick on $ext_if proto {tcp, udp} from any to any port {$voip_udp_port, $voip_tcp_port} keep state queue voip_out
pass out log (all) quick on $ext_if proto {tcp, udp} from any to any port {$voip_udp_port, $voip_tcp_port} keep state queue voip_out
# Others
pass out log quick on $ext_if inet proto tcp from $ext_if to any port $ssh_ports flags S/SA synproxy state queue ssh_out
pass out log quick on $ext_if inet proto {tcp, udp} from $ext_if to any port $web_ports flags S/SA keep state queue www_out
pass out log quick on $ext_if inet proto {tcp, udp} from $ext_if to any port $other_ports flags S/SA keep state queue others_out
## Assigned to Queue inbound
# VoIP
#pass in from any to $voip_srv
pass in log (all) quick on $int_if proto {tcp, udp} from any to any port {$voip_udp_port, $voip_tcp_port} keep state queue voip_in
pass out log (all) quick on $int_if proto {tcp, udp} from any to any port {$voip_udp_port, $voip_tcp_port} keep state queue voip_in
# Others
pass out log quick on $int_if inet proto tcp from $ext_if to any port $ssh_ports flags S/SA synproxy state queue ssh_in
pass out log quick on $int_if inet proto {tcp, udp} from $ext_if to any port $web_ports flags S/SA keep state queue www_in
pass out log quick on $int_if inet proto {tcp, udp} from $ext_if to any port $other_ports flags S/SA keep state queue others_in
------ end ------
HFSC :
----- begin -----
# $ Analisa Performansi Trafik VoIP terhadap QoS OpenBSD-Firewall $
# PF Rules for HFSC2
#
### MACROS ###
# Interfaces
ext_if="rl0"
int_if="rl1"
# IPs
web_srv="172.16.17.2"
ssh_srv="172.16.17.2"
voip_srv="172.16.17.2"
# Ports
web_ports="{www, https}"
ssh_ports="{22,3210}"
other_ssh_port="3210"
voip_tcp_port="5060"
voip_udp_ports="4569"
other_ports="{2000, 4520}"
# Service
icmp_allow="echoreq"
### OPTIONS ###
set block-policy drop
set optimization aggressive
set skip on lo0
set loginterface rl0
set loginterface rl1
### SCRUB ###
scrub in all fragment reassemble
### QUALITY OF SERVICE ###
## Queue Rule ##
# Parent Rule For Queueing on the external interface
altq on $ext_if hfsc bandwidth 100% queue { voip_srvr_out, others_out }
#Child queue definition
queue voip_srvr_out hfsc bandwidth 99% { voip_traffic_out, ssh_traffic_out, www_traffic_out }
queue voip_traffic_out bandwidth 87% hfsc (rio, realtime (80% 3700 79%))
queue ssh_traffic_out bandwidth 5% hfsc (linkshare (5% 3000 4%))
queue www_traffic_out bandwidth 3% hfsc (linkshare (3% 2900 2%))
queue others_out bandwidth 1% hfsc (default)
# Parent Rule For Queueing on the internal interface
altq on $int_if hfsc bandwidth 100% queue { voip_srvr_in, others_in }
#Child queue definition
queue voip_srvr_in hfsc bandwidth 98% { voip_traffic_in, ssh_traffic_in, www_traffic_in }
queue voip_traffic_in bandwidth 90% hfsc (ecn, linkshare (85% 3100 80%))
queue ssh_traffic_in bandwidth 5% hfsc (linkshare (5% 3000 4%))
queue www_traffic_in bandwidth 3% hfsc (linkshare (3% 2900 2%))
queue others_in bandwidth 1% hfsc (default)
### PACKET REDIRECTION ###
# Outgoing
nat on $ext_if inet proto {tcp, udp} from $voip_srv to any port $other_ports -> $ext_if static-port
nat on $ext_if inet proto {tcp, udp} from $voip_srv to any port $voip_udp_ports -> $ext_if static-port
nat on $ext_if from $int_if:network to any -> $ext_if
# Incoming
rdr on $ext_if inet proto {tcp, udp} from any to any port $voip_udp_ports -> $voip_srv port $voip_udp_ports
rdr on $ext_if inet proto {tcp, udp} from any to any port $other_ports -> $voip_srv
rdr on $ext_if inet proto tcp from any to $ext_if port $web_ports -> $web_srv
rdr on $ext_if inet proto tcp from any to $ext_if port ssh -> $ssh_srv port ssh
rdr on $ext_if inet proto tcp from any to $ext_if port $other_ssh_port -> $ext_if
### FILTER PACKETS ###
# Basic
block log all
#pass all
pass quick on lo0 all
pass out log (all) quick on $ext_if from $ext_if to any flags S/SA modulate state
pass in log (all) quick on $int_if from $web_srv to any flags S/SA
# Web Server
pass in on $ext_if inet proto tcp from any to $web_srv port $web_ports flags S/SA synproxy state
pass out on $int_if inet proto tcp from any to $web_srv port $web_ports flags S/SA keep state
# ICMP
pass in inet proto icmp all icmp-type $icmp_allow keep state
pass out inet proto icmp all keep state
# SSH
pass in quick on $ext_if inet proto tcp from any to $ssh_srv port = ssh flags S/SAFR modulate state
pass out quick on $int_if inet proto tcp from any to $ssh_srv port = ssh flags S/SAFR modulate state
pass out quick on $ext_if inet proto tcp all flags S/SAFR modulate state
pass in quick on $ext_if inet proto tcp from any to $ext_if port $ssh_ports flags S/SA synproxy state
# VoIP
pass in log (all) quick on $ext_if inet proto {tcp, udp} from any port {$voip_udp_ports, $voip_tcp_port} to any port { $voip_udp_ports, $voip_tcp_port } flags S/SAFR keep state
pass out log (all) quick on $ext_if inet proto {tcp, udp} from any port {$voip_udp_ports, $voip_tcp_port} to any port { $voip_udp_ports, $voip_tcp_port } flags S/SAFR keep state
pass in log (all) quick on $ext_if inet proto {tcp, udp} from any port $other_ports to any port $other_ports flags S/SAFR keep state
pass out log (all) quick on $ext_if inet proto {tcp, udp} from any port $other_ports to any port $other_ports flags S/SAFR keep state
## Assigned to Queue Outbound
# VoIP
pass in log (all) quick on $ext_if inet proto udp from any to any port {$voip_udp_ports, $voip_tcp_port} keep state queue voip_traffic_out
pass out log (all) quick on $ext_if inet proto udp from any to any port {$voip_udp_ports, $voip_tcp_port} keep state queue voip_traffic_out
# Other
pass out log quick on $ext_if inet proto tcp from $ext_if to any port $ssh_ports flags S/SA synproxy state queue ssh_traffic_out
pass out log quick on $ext_if inet proto {tcp, udp} from $ext_if to any port $web_ports flags S/SA keep state queue www_traffic_out
pass out log quick on $ext_if inet proto {tcp, udp} from $ext_if to any port $other_ports flags S/SA keep state queue others_out
## Assigned to Queue Inbound
# VoIP
pass in log (all) quick on $int_if inet proto udp from any to any port {$voip_udp_ports, $voip_tcp_port} keep state queue voip_traffic_in
pass out log (all) quick on $int_if inet proto udp from any to any port {$voip_udp_ports, $voip_tcp_port} keep state queue voip_traffic_in
# Other
pass out log quick on $int_if inet proto tcp from $ext_if to any port $ssh_ports flags S/SA synproxy state queue ssh_traffic_in
pass out log quick on $int_if inet proto {tcp, udp} from $ext_if to any port $web_ports flags S/SA keep state queue www_traffic_in
pass out log quick on $int_if inet proto {tcp, udp} from $ext_if to any port $other_ports flags S/SA keep state queue others_in
----- end -----
[Simulation]
Simulation consist of three parts, every part for one kind of packet scheduling algorithm. The scenario run like this:
At Firewall-NAT Gateway:
1. Change PF rules due to packet scheduling test scenario : # pfctl -f /etc/pfrules
2. At the end of every test, user running this command : pfstat -q -p -c /etc/pfstat.conf -d /var/log/pfstat
At Server:
1. Running http server daemon.
2. Running Asterisk server.
3. Running voip packet generator's script for server mode, the script code:
#!/usr/bin/perl -w
#
# VoIP Traffic Generator - Server
# Bruno Benchimol <brunobenchimol@terra.com.br
# litle modified by Fuad
use IO::Socket::INET;
use Getopt::Long;
print " >>>> VoIP Traffic Generator <<<<\n";
print " Server Mode \n";
if (@ARGV < 1) {
print "Not enough parameters.\n\n";
print "Usage: --port, -p port to bind server\n";
exit(-1);
}
GetOptions("port|p=i" => \$port);
# Create a new socket
$Socket = new IO::Socket::INET->new (LocalPort=> $port,
Proto=> 'udp');
print "\nReady to accept connections on port $port...\n";
$count=0;
# never close server
while(1)
{
$Socket->recv($text,1470);
$count++;
# process summary information if status is found in msg
if($text =~ /status/)
{
($text, $packets) = split (/,/, $text);
# discard last packet since its a "summary packet" (small data)
$count--;
print "Packets expected: $packets\n";
print "Packets Received: $count\n";
$packetloss = ($packets - $count);
$packetlossperc = ($packetloss / $packets) * 100;
print "Packet Loss: $packetloss ($packetlossperc%)\n";
# reset packet counter
$count=0;
}
}
----- end -----
At Client :
1. User running browser and accesing the web server
2. User running softphone client and try making connection
3. User running voip packet generator's script for client mode, the script code:
#!/usr/bin/perl -w
#Bruno Benchimol <brunobenchimol@terra.com.br
#litle modified by Fuad
use Time::HiRes qw(usleep ualarm gettimeofday);
use IO::Socket::INET;
use Getopt::Long;
print " >>>> VoIP Traffic Generator <<<<\n";
print " Client Mode \n";
sub QueryStatistics
{
# Create a new socket
$Socket=new IO::Socket::INET->new (PeerPort=>$port,
Proto=>'udp',
PeerAddr=>$peer)
or die "Couldnt connect to host $peer on port $port using udp\n";
$smsg="status,$_[0]";
if(!$Socket->send($smsg))
{
print "Socket failed to send data !!!\n";
}
}
# Send 1 second burst!
sub SendBurst
{
# Create a new socket
$Socket=new IO::Socket::INET->new (PeerPort=>$port,
Proto=>'udp',
PeerAddr=>$peer)
or die "Couldnt connect to host $peer on port $port using udp\n";
$count_duration=0;
$duration = $_[0];
$count=0;
$pps=$_[1];
# calculte inter-packet time (in microseconds)
$sleep_time = (1/$pps)*100;
while($count_duration < $duration)
{
# reset inner counter so it will run again
$count = 0;
while($count < $pps)
{
if(!$Socket->send($msg))
{
print "Socket failed to send data !!!\n";
}
$count++;
# microseconds sleep time
Time::HiRes::usleep($sleep_time);
}
$count_duration++;
}
}
sub usage
{
print <<END
--size, -s payload size of udp packet (bytes)
--pps, -k packets per second
--time, -t time of the duration of test (seconds)
--streams, -m number of parallel connections (streams)
--port, -p port to connect
--host, -h ip to connect
END
}
## >>>>>> Main Program <<<<<
if (@ARGV < 6)
{
print "\nNot enough arguments.\n";
usage();
exit(-1);
}
# parameters
GetOptions ("size|s=i" => \$udp_payload_size,
"pps|k=i" => \$packet_per_second,
"time|t=i" => \$duration_test,
"streams|m=i" => \$maxfork,
"port|p=i" => \$port,
"host|h=s" => \$peer);
print "\nConnecting to $peer on $port, crafting UDP packets with payload of $udp_payload_size bytes, sending $packet_per_second packets per second, test will run for $duration_test seconds and has $maxfork streams. \n\n";
# udp payload size in bytes
$msg = "";
for ($i=0 ; $i < $udp_payload_size; $i++) {
$msg .= ".";
}
# expected number of packets to send
$totalpackets = $packet_per_second * $duration_test * $maxfork;
$ifork=0;
print "Spawning childrens processes ...\n";
while ($ifork < $maxfork)
{
if (fork) {
# parent do almost nothing
$ifork++;
} else {
# child send burst
&SendBurst($duration_test, $packet_per_second);
exit(0);
}
}
print "Waiting on childrens to finish ...\n";
print "Total Packets expected to be sent: " . $totalpackets;
# wait childrens to finish
wait();
print "\nTraffic Sent, now making server dump statistics on screen, wait...\n";
sleep(1);
&QueryStatistics($totalpackets);
print "Done, Check Server Screen.\n";
exit(0);
--------------- end ---------------
That script running via console with this command: ./voip-gen-client.pl --size 160 --pps 50 --time 307 --streams 57 --port 4569 -host 10.14.15.26

Anonymous # Friday, April 16, 2010 12:35:37 PM