Skip to content

Commit a95c088

Browse files
author
QuasarStream Team
committed
Add ICE Setting and minor improvements
1 parent 911f986 commit a95c088

File tree

7 files changed

+134
-34
lines changed

7 files changed

+134
-34
lines changed

.github/FUNDING.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
github: [php-webrtc]
1+
github:
2+
- php-webrtc
3+
- quasarstream
4+

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
88
## [1.0.0] - 2025-05-13
99

1010
### Added
11-
- First release
11+
- First release
12+
13+
14+
## [1.0.3] - 2025-10-08
15+
16+
### Added
17+
- Add ICESetting class that represent low level ice setting

src/RTCICESetting.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace Webrtc\ICE;
4+
5+
use Webrtc\Exception\InvalidArgumentException;
6+
use Webrtc\ICE\Enum\IceRole;
7+
use Webrtc\ICE\Enum\TransportPolicyType;
8+
9+
class RTCICESetting
10+
{
11+
private ?array $icePortRange = null;
12+
private TransportPolicyType $transportPolicy = TransportPolicyType::ALL;
13+
private ?array $nat1to1 = null;
14+
private bool $iceLite = false;
15+
// it will be changed for only testing purpose
16+
private IceRole $iceRole = IceRole::Controlling;
17+
18+
public function getIcePortRange(): ?array
19+
{
20+
return $this->icePortRange;
21+
}
22+
23+
public function setIcePortRange(int $minPort, int $maxPort): void
24+
{
25+
if ($maxPort- $minPort < 100) {
26+
throw new InvalidArgumentException("maxPort - minPort must be greater than 100");
27+
}
28+
29+
if ($minPort < 1024 || $maxPort > 65535 || $minPort > $maxPort) {
30+
throw new InvalidArgumentException("Invalid port range [$minPort, $maxPort]");
31+
}
32+
33+
$this->icePortRange = [$minPort, $maxPort];
34+
}
35+
36+
public function getTransportPolicy(): TransportPolicyType
37+
{
38+
return $this->transportPolicy;
39+
}
40+
41+
public function setTransportPolicy(TransportPolicyType $transportPolicy): void
42+
{
43+
$this->transportPolicy = $transportPolicy;
44+
}
45+
46+
public function getNat1to1(): ?array
47+
{
48+
return $this->nat1to1;
49+
}
50+
51+
public function setNat1to1(?array $nat1to1): void
52+
{
53+
$this->nat1to1 = $nat1to1;
54+
}
55+
56+
public function isIceLite(): bool
57+
{
58+
return $this->iceLite;
59+
}
60+
61+
public function setIceLite(bool $iceLite): void
62+
{
63+
$this->iceLite = $iceLite;
64+
}
65+
66+
public function getIceRole(): IceRole
67+
{
68+
return $this->iceRole;
69+
}
70+
71+
public function setIceRole(IceRole $iceRole): void
72+
{
73+
$this->iceRole = $iceRole;
74+
}
75+
76+
}

src/RTCIceConnection.php

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ class RTCIceConnection extends EventEmitter implements RTCIceConnectionInterface
7171
{
7272
use NetworkAdapter, Mdns, DNS;
7373

74-
use NetworkAdapter, Mdns, DNS;
75-
7674
/* Constants */
7775

7876
/** @var int Maximum number of binding retry attempts */
@@ -179,15 +177,14 @@ class RTCIceConnection extends EventEmitter implements RTCIceConnectionInterface
179177
/** @var int Count of failed binding attempts */
180178
private int $tryFailedCount = 0;
181179

180+
/** @var ?array Range of ports that host candidates allow */
182181
private ?array $icePortRange = null;
183182

184183
/**
185-
* Constructor - Creates a new ICE connection
186-
*
187-
* @param RTCIceProtocolConfigurationInterface $configuration ICE protocol configuration
188-
* @param IceRole $iceRole The role of this ICE agent
189-
* @throws RandomException If random number generation fails
184+
* @var ?array If set, this will result in all host candidates (which normally have a private IP address)
185+
* to be rewritten with the public address provided in the settings
190186
*/
187+
private ?array $nat1to1 = null;
191188

192189
/**
193190
* Constructor - Creates a new ICE connection
@@ -454,7 +451,7 @@ private function getCandidate(int $componentId): array
454451
*/
455452
private function getHostCandidates(int $componentId): array
456453
{
457-
$addresses = $this->getHostAddresses($this->useIPv4, $this->useIPv6);
454+
$addresses = $this->nat1to1 ?? $this->getHostAddresses($this->useIPv4, $this->useIPv6);
458455
$candidates = [];
459456

460457
foreach ($addresses as $address) {
@@ -2065,4 +2062,14 @@ public function setIcePortRange(?array $icePortRange): void
20652062
{
20662063
$this->icePortRange = $icePortRange;
20672064
}
2065+
2066+
public function getNat1to1(): ?array
2067+
{
2068+
return $this->nat1to1;
2069+
}
2070+
2071+
public function setNat1to1(?array $nat1to1): void
2072+
{
2073+
$this->nat1to1 = $nat1to1;
2074+
}
20682075
}

src/RTCIceGatherer.php

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
use Random\RandomException;
1717
use Throwable;
1818
use Webrtc\ICE\Enum\IceGatheringState;
19-
use Webrtc\ICE\Enum\IceRole;
20-
use Webrtc\ICE\Enum\TransportPolicyType;
2119

2220
/**
2321
* The RTCIceGatherer is responsible for gathering ICE candidates on the local machine.
@@ -40,29 +38,27 @@ class RTCIceGatherer extends EventEmitter implements RTCIceGathererInterface
4038
* Initializes ICE connection with the given ICE servers and role. Optionally accepts a logger.
4139
*
4240
* @param array $iceServes List of ICE server configurations.
43-
* @param IceRole $role The ICE role (Controlling or Controlled).
41+
* @param ?RTCICESetting $setting The ICE settings.
4442
* @param LoggerInterface|null $logger Optional logger for debugging.
4543
*
4644
* @throws RandomException
4745
*/
48-
public function __construct(
49-
private readonly array $iceServes,
50-
?array $icePortRange = null,
51-
?TransportPolicyType $transportPolicy = null,
52-
IceRole $role = IceRole::Controlling,
53-
?LoggerInterface $logger = null
54-
)
46+
public function __construct(private array $iceServes, ?RTCICESetting $setting = null, ?LoggerInterface $logger = null)
5547
{
5648
$protocolParser = new IceProtocolParser($iceServes);
57-
$this->iceConnection = new RTCIceConnection($protocolParser->getIceConnectionConfiguration(), $role);
58-
$this->iceConnection->setIcePortRange($icePortRange);
5949

60-
if ($logger) {
61-
$this->iceConnection->setLogger($logger);
50+
if (!$setting) {
51+
$setting = new RTCICESetting();
6252
}
6353

64-
if ($transportPolicy) {
65-
$this->iceConnection->setTransportPolicy($transportPolicy);
54+
$this->iceConnection = new RTCIceConnection($protocolParser->getIceConnectionConfiguration(), $setting->getIceRole());
55+
$this->iceConnection->setIcePortRange($setting->getIcePortRange());
56+
$this->iceConnection->setTransportPolicy($setting->getTransportPolicy());
57+
$this->iceConnection->setRemoteIsLite($setting->isIceLite());
58+
$this->iceConnection->setNat1to1($setting->getNat1to1());
59+
60+
if ($logger) {
61+
$this->iceConnection->setLogger($logger);
6662
}
6763
}
6864

tests/RTCIceConnectionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public function testConnectToIceLiteNominationFails()
410410
$this->inviteAccept($connection1, $connection2);
411411

412412
async(function () use ($connection1, $connection2) {
413-
delay(1);
413+
delay(5);
414414
$connection1->close();
415415
$connection2->close();
416416
})();

tests/RTCIceTransportTest.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?php
22

3-
namespace Tests\Webrtc\ICE;
43

54
use PHPUnit\Framework\Attributes\CoversClass;
65
use PHPUnit\Framework\Attributes\UsesClass;
@@ -20,6 +19,7 @@
2019
use Webrtc\ICE\RTCIceGatherer;
2120
use Webrtc\ICE\RTCIceParameters;
2221
use Webrtc\ICE\RTCIceProtocolConfiguration;
22+
use Webrtc\ICE\RTCICESetting;
2323
use Webrtc\ICE\RTCIceTransport;
2424
use Webrtc\ICE\Trait\Mdns;
2525
use Webrtc\ICE\Trait\NetworkAdapter;
@@ -107,10 +107,14 @@ public function testConstruct()
107107

108108
public function testConnect()
109109
{
110-
$gatherer1 = new RTCIceGatherer([], role: IceRole::Controlling);
110+
$iceSetting1 = new RTCICESetting;
111+
$iceSetting1->setIceRole(IceRole::Controlling);
112+
$gatherer1 = new RTCIceGatherer([], $iceSetting1);
111113
$transport1 = new RTCIceTransport($gatherer1);
112114

113-
$gatherer2 = new RTCIceGatherer([], role: IceRole::Controlled);
115+
$iceSetting2 = new RTCICESetting;
116+
$iceSetting2->setIceRole(IceRole::Controlled);
117+
$gatherer2 = new RTCIceGatherer([], $iceSetting2);
114118
$transport2 = new RTCIceTransport($gatherer2);
115119

116120
$gatherer1->gather();
@@ -140,10 +144,14 @@ public function testConnect()
140144

141145
public function testConnectFail()
142146
{
143-
$gatherer1 = new RTCIceGatherer([], role: IceRole::Controlling);
147+
$iceSetting1 = new RTCICESetting;
148+
$iceSetting1->setIceRole(IceRole::Controlling);
149+
$gatherer1 = new RTCIceGatherer([], $iceSetting1);
144150
$transport1 = new RTCIceTransport($gatherer1);
145151

146-
$gatherer2 = new RTCIceGatherer([], role: IceRole::Controlled);
152+
$iceSetting2 = new RTCICESetting;
153+
$iceSetting2->setIceRole(IceRole::Controlled);
154+
$gatherer2 = new RTCIceGatherer([], $iceSetting2);
147155
$transport2 = new RTCIceTransport($gatherer2);
148156

149157
$gatherer1->gather();
@@ -173,10 +181,14 @@ public function testConnectFail()
173181

174182
public function testConnectThenConsentExpires()
175183
{
176-
$gatherer1 = new RTCIceGatherer([], role: IceRole::Controlling);
184+
$iceSetting1 = new RTCICESetting;
185+
$iceSetting1->setIceRole(IceRole::Controlling);
186+
$gatherer1 = new RTCIceGatherer([], $iceSetting1);
177187
$transport1 = new RTCIceTransport($gatherer1);
178188

179-
$gatherer2 = new RTCIceGatherer([], role: IceRole::Controlled);
189+
$iceSetting2 = new RTCICESetting;
190+
$iceSetting2->setIceRole(IceRole::Controlled);
191+
$gatherer2 = new RTCIceGatherer([], $iceSetting2);
180192
$transport2 = new RTCIceTransport($gatherer2);
181193

182194
$gatherer1->gather();

0 commit comments

Comments
 (0)