Skip to content

Commit d953fe5

Browse files
authored
Merge pull request #12 from rtckit/v0.3.3
v0.3.3
2 parents d0f9a6f + 109834c commit d953fe5

File tree

4 files changed

+100
-6
lines changed

4 files changed

+100
-6
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "rtckit/sip",
33
"description": "Parser/Renderer for SIP protocol written in PHP",
4-
"version": "0.3.2",
4+
"version": "0.3.3",
55
"type": "library",
66
"keywords": [
77
"sip",

src/Header/ViaHeader.php

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,38 @@ public static function parse(array $hbody): ViaHeader
8080

8181
$pv = isset($p[1]) ? trim($p[1]) : '';
8282

83-
if ($p[0] === 'branch') {
84-
$val->branch = $pv;
85-
} else {
86-
$val->params[$p[0]] = $pv;
83+
switch ($p[0]) {
84+
case 'branch':
85+
$val->branch = $pv;
86+
break;
87+
88+
case 'received':
89+
if (!filter_var($pv, FILTER_VALIDATE_IP)) {
90+
throw new InvalidHeaderParameter('Invalid Via header received parameter', Response::BAD_REQUEST);
91+
}
92+
93+
$val->received = $pv;
94+
break;
95+
96+
case 'rport':
97+
if (!strlen($pv)) {
98+
$val->rport = 0;
99+
} else if (!ctype_digit($pv)) {
100+
throw new InvalidHeaderParameter('Invalid Via header rport parameter', Response::BAD_REQUEST);
101+
}
102+
103+
$rport = (int)$pv;
104+
105+
if ($rport > 65535) {
106+
throw new InvalidHeaderParameter('Invalid Via header rport parameter', Response::BAD_REQUEST);
107+
}
108+
109+
$val->rport = $rport;
110+
break;
111+
112+
default:
113+
$val->params[$p[0]] = $pv;
114+
break;
87115
}
88116
}
89117

@@ -117,6 +145,18 @@ public function render(string $hname): string
117145
$ret .= ";branch={$value->branch}";
118146
}
119147

148+
if (isset($value->received)) {
149+
$ret .= ";received={$value->received}";
150+
}
151+
152+
if (isset($value->rport)) {
153+
if (!$value->rport) {
154+
$ret .= ";rport";
155+
} else {
156+
$ret .= ";rport={$value->rport}";
157+
}
158+
}
159+
120160
foreach ($value->params as $pk => $pv) {
121161
$ret .= ';' . $pk . (!isset($pv[0]) ? '' : "={$pv}");
122162
}

src/Header/ViaValue.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ class ViaValue
2626
/** @var string Via branch parameters */
2727
public string $branch;
2828

29+
/** @var string Source IP address, different than the Via host */
30+
public string $received;
31+
32+
/** @var int Response port */
33+
public int $rport;
34+
2935
/** @var array<string, string> Additional parameters */
3036
public array $params = [];
3137
}

tests/Header/ViaHeaderTest.php

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,30 @@ public function testShouldNotParseMissingHost()
6868
ViaHeader::parse(['SIP/2.0/TCP']);
6969
}
7070

71+
public function testShouldNotParseEmptyReceivedParameter()
72+
{
73+
$this->expectException(InvalidHeaderParameter::class);
74+
ViaHeader::parse(['SIP/2.0/TCP 178.73.76.230:5060;branch=z9hG4bKiokioukju908;received']);
75+
}
76+
77+
public function testShouldNotParseNonIPReceivedParameter()
78+
{
79+
$this->expectException(InvalidHeaderParameter::class);
80+
ViaHeader::parse(['SIP/2.0/TCP 178.73.76.230:5060;branch=z9hG4bKiokioukju908;received=some.fqdn.com']);
81+
}
82+
83+
public function testShouldNotParseNonNumericRPortParameter()
84+
{
85+
$this->expectException(InvalidHeaderParameter::class);
86+
ViaHeader::parse(['SIP/2.0/TCP 178.73.76.230:5060;branch=z9hG4bKiokioukju908;rport=onethousandtwentyfour']);
87+
}
88+
89+
public function testShouldNotParseLargeRPortParameter()
90+
{
91+
$this->expectException(InvalidHeaderParameter::class);
92+
ViaHeader::parse(['SIP/2.0/TCP 178.73.76.230:5060;branch=z9hG4bKiokioukju908;rport=318272']);
93+
}
94+
7195
public function testShouldNotParseEmptyParameterNames()
7296
{
7397
$this->expectException(InvalidHeaderParameter::class);
@@ -83,14 +107,38 @@ public function testShouldRenderWellFormedValues()
83107
$via->values[0]->transport = 'UDP';
84108
$via->values[0]->host = '192.0.2.4:5060';
85109
$via->values[0]->branch = 'z9hG4bKnashds7';
110+
$via->values[0]->received = '64.52.36.12';
111+
$via->values[0]->rport = 1025;
112+
$via->values[0]->params['custom'] = 'something';
113+
114+
$rendered = $via->render('Via');
115+
116+
$this->assertNotNull($rendered);
117+
$this->assertIsString($rendered);
118+
$this->assertEquals(
119+
'Via: SIP/2.0/UDP 192.0.2.4:5060;branch=z9hG4bKnashds7;received=64.52.36.12;rport=1025;custom=something' . "\r\n",
120+
$rendered
121+
);
122+
}
123+
124+
public function testShouldRenderEmptyRPort()
125+
{
126+
$via = new ViaHeader;
127+
$via->values[0] = new ViaValue;
128+
$via->values[0]->protocol = 'SIP';
129+
$via->values[0]->version = '2.0';
130+
$via->values[0]->transport = 'UDP';
131+
$via->values[0]->host = '192.0.2.4:5060';
132+
$via->values[0]->branch = 'z9hG4bKnashds7';
133+
$via->values[0]->rport = 0;
86134
$via->values[0]->params['custom'] = 'something';
87135

88136
$rendered = $via->render('Via');
89137

90138
$this->assertNotNull($rendered);
91139
$this->assertIsString($rendered);
92140
$this->assertEquals(
93-
'Via: SIP/2.0/UDP 192.0.2.4:5060;branch=z9hG4bKnashds7;custom=something' . "\r\n",
141+
'Via: SIP/2.0/UDP 192.0.2.4:5060;branch=z9hG4bKnashds7;rport;custom=something' . "\r\n",
94142
$rendered
95143
);
96144
}

0 commit comments

Comments
 (0)