Skip to content

Commit 1f2c8f5

Browse files
author
Alexander Pekhota
committed
IPv6 support #78
1 parent a48cde0 commit 1f2c8f5

File tree

6 files changed

+181
-8
lines changed

6 files changed

+181
-8
lines changed

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,43 @@ ZIPKIN_OVER_COMPACT_UDP | 5775
161161
JAEGER_OVER_BINARY_UDP | 6832
162162
JAEGER_OVER_BINARY_HTTP | 14268
163163

164+
## IPv6
165+
166+
In case you need IPv6 support you need to set `ip_version` Config variable.
167+
By default, IPv4 is used. There is an alias `Config::IP_VERSION` which you can use
168+
as an alternative to raw `ip_version`.
169+
170+
Example:
171+
172+
```php
173+
use Jaeger\Config;
174+
175+
$config = new Config(
176+
[
177+
"ip_version" => Config::IPV6, // <-- or use Config::IP_VERSION constant
178+
'logging' => true,
179+
'dispatch_mode' => Config::JAEGER_OVER_BINARY_UDP,
180+
],
181+
'serviceNameExample',
182+
);
183+
$config->initializeTracer();
184+
```
185+
or
186+
187+
```php
188+
use Jaeger\Config;
189+
190+
$config = new Config(
191+
[
192+
Config::IP_VERSION => Config::IPV6, // <--
193+
'logging' => true,
194+
'dispatch_mode' => Config::JAEGER_OVER_BINARY_UDP,
195+
],
196+
'serviceNameExample',
197+
);
198+
$config->initializeTracer();
199+
```
200+
164201

165202
## Testing
166203

src/Jaeger/Config.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,15 @@
2121

2222
class Config
2323
{
24+
const IP_VERSION = "ip_version";
25+
2426
const ZIPKIN_OVER_COMPACT_UDP = "zipkin_over_compact_udp";
2527
const JAEGER_OVER_BINARY_UDP = "jaeger_over_binary_udp";
2628
const JAEGER_OVER_BINARY_HTTP = "jaeger_over_binary_http";
2729

30+
const IPV6 = "IPv6";
31+
const IPV4 = "IPv4";
32+
2833
/**
2934
* @return string[]
3035
*/
@@ -88,7 +93,12 @@ public function __construct(
8893
$this->config["dispatch_mode"] = self::ZIPKIN_OVER_COMPACT_UDP;
8994
}
9095

96+
if (empty($this->config[Config::IP_VERSION])) {
97+
$this->config[Config::IP_VERSION] = self::IPV4;
98+
}
99+
91100
$this->serviceName = $this->config['service_name'] ?? $serviceName;
101+
92102
if ($this->serviceName === null) {
93103
throw new Exception('service_name required in the config or param.');
94104
}
@@ -324,6 +334,11 @@ private function shouldUseOneSpanPerRpc(): bool
324334
return $this->config['one_span_per_rpc'] ?? true;
325335
}
326336

337+
public function ipProtocolVersion(): string
338+
{
339+
return $this->config[self::IP_VERSION] ?? self::IPV4;
340+
}
341+
327342
/**
328343
* Sets values from env vars into config props, unless ones has been already set.
329344
*/
@@ -367,5 +382,9 @@ private function setConfigFromEnv()
367382
if (isset($_ENV['JAEGER_SAMPLER_PARAM']) && !isset($this->config['sampler']['param'])) {
368383
$this->config['sampler']['param'] = $_ENV['JAEGER_SAMPLER_PARAM'];
369384
}
385+
386+
if (isset($_ENV['IP_VERSION']) && !isset($this->config[Config::IP_VERSION])) {
387+
$this->config[Config::IP_VERSION] = $_ENV['IP_VERSION'];
388+
}
370389
}
371390
}

src/Jaeger/ReporterFactory/JaegerReporterFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ public function createReporter() : ReporterInterface
1919
$udp = new ThriftUdpTransport(
2020
$this->config->getLocalAgentReportingHost(),
2121
$this->config->getLocalAgentReportingPort(),
22-
$this->config->getLogger()
22+
$this->config->getLogger(),
23+
$this->config
2324
);
2425

2526
$transport = new TBufferedTransport(

src/Jaeger/ReporterFactory/ZipkinReporterFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ public function createReporter() : ReporterInterface
2323
$udp = new ThriftUdpTransport(
2424
$this->config->getLocalAgentReportingHost(),
2525
$this->config->getLocalAgentReportingPort(),
26-
$this->config->getLogger()
26+
$this->config->getLogger(),
27+
$this->config
2728
);
2829

2930
$transport = new TBufferedTransport(

src/Jaeger/ThriftUdpTransport.php

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,55 @@ class ThriftUdpTransport extends TTransport
2525
*/
2626
private $logger;
2727

28+
/**
29+
* @var Config
30+
*/
31+
private $config;
32+
2833
/**
2934
* ThriftUdpTransport constructor.
3035
* @param string $host
3136
* @param int $port
3237
* @param LoggerInterface $logger
3338
*/
34-
public function __construct(string $host, int $port, LoggerInterface $logger = null)
39+
public function __construct(string $host, int $port, LoggerInterface $logger = null, Config $config = null)
3540
{
41+
$this->setLogger($logger);
42+
43+
$this->config = $config;
44+
45+
$ipProtocol = $this->ipProtocolVersion();
46+
$this->socket = $this->createSocket($ipProtocol);
47+
3648
$this->host = $host;
3749
$this->port = $port;
38-
$this->socket = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
39-
if ($this->socket === false) {
50+
}
51+
52+
protected function setLogger($logger)
53+
{
54+
$this->logger = $logger ?? new NullLogger();
55+
}
56+
57+
protected function createSocket(string $ipProtocol)
58+
{
59+
$socketDomain = AF_INET;
60+
if ($ipProtocol === Config::IPV6) {
61+
$socketDomain = AF_INET6;
62+
}
63+
64+
$socket = @socket_create($socketDomain, SOCK_DGRAM, SOL_UDP);
65+
if ($socket === false) {
4066
$this->handleSocketError("socket_create failed");
4167
}
42-
$this->logger = $logger ?? new NullLogger();
68+
return $socket;
69+
}
70+
71+
protected function ipProtocolVersion()
72+
{
73+
if (!empty($this->config)) {
74+
return $this->config->ipProtocolVersion();
75+
}
76+
return "";
4377
}
4478

4579
/**

tests/Jaeger/ThriftUdpTransportTest.php

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace Jaeger\Tests;
44

5+
use Jaeger\Config;
56
use Jaeger\Tests\Logger\StackLogger;
67
use Jaeger\ThriftUdpTransport;
8+
use Jaeger\Tracer;
79
use PHPUnit\Framework\TestCase;
810
use Thrift\Exception\TTransportException;
911

@@ -52,7 +54,8 @@ public function testClose()
5254
$this->assertEquals($this->logger->getMessagesCount(), 0);
5355
}
5456

55-
public function testDoubleClose() {
57+
public function testDoubleClose()
58+
{
5659
$this->assertEquals($this->logger->getMessagesCount(), 0);
5760
$this->transport->close();
5861
$this->assertEquals($this->logger->getMessagesCount(), 0);
@@ -64,7 +67,8 @@ public function testDoubleClose() {
6467
);
6568
}
6669

67-
public function testException() {
70+
public function testException()
71+
{
6872
$this->assertEquals($this->logger->getMessagesCount(), 0);
6973
$this->transport->open();
7074
$this->assertEquals($this->logger->getMessagesCount(), 0);
@@ -80,6 +84,83 @@ public function testException() {
8084
} else {
8185
$this->assertRegExp($pattern, $msg);
8286
}
87+
}
88+
89+
public function testProtocolVersionIPv4()
90+
{
91+
$config = new Config([
92+
Config::IP_VERSION => Config::IPV4
93+
], "testServiceName");
94+
95+
$transport = new ThriftUdpTransport('127.0.0.1', 12345, $this->logger, $config);
96+
97+
$reflectionTransport = new \ReflectionClass($transport);
98+
$ipProtocolVersionMethod = $reflectionTransport->getMethod("ipProtocolVersion");
99+
$ipProtocolVersionMethod->setAccessible(true);
100+
101+
$this->assertEquals(Config::IPV4, $ipProtocolVersionMethod->invoke($transport));
102+
}
103+
104+
public function testProtocolVersionIPv6()
105+
{
106+
$config = new Config([
107+
Config::IP_VERSION => Config::IPV6
108+
], "testServiceName");
109+
110+
$transport = new ThriftUdpTransport('127.0.0.1', 12345, $this->logger, $config);
111+
//
112+
$reflectionTransport = new \ReflectionClass($transport);
113+
$ipProtocolVersionMethod = $reflectionTransport->getMethod("ipProtocolVersion");
114+
$ipProtocolVersionMethod->setAccessible(true);
115+
//
116+
$this->assertEquals(Config::IPV6, $ipProtocolVersionMethod->invoke($transport));
117+
}
118+
119+
public function testProtocolVersionDefault()
120+
{
121+
$config = new Config([
122+
], "testServiceName");
123+
124+
$transport = new ThriftUdpTransport('127.0.0.1', 12345, $this->logger, $config);
125+
126+
$reflectionTransport = new \ReflectionClass($transport);
127+
$ipProtocolVersionMethod = $reflectionTransport->getMethod("ipProtocolVersion");
128+
$ipProtocolVersionMethod->setAccessible(true);
129+
130+
$this->assertEquals(Config::IPV4, $ipProtocolVersionMethod->invoke($transport));
131+
}
132+
133+
public function testCreateSocket()
134+
{
135+
$transport = $this->getMockBuilder(ThriftUdpTransport::class)
136+
->disableOriginalConstructor()
137+
->getMock();
138+
139+
$reflectionClass = new \ReflectionClass($transport);
140+
$method = $reflectionClass->getMethod("setLogger");
141+
$method->setAccessible(true);
142+
$method->invokeArgs($transport, [$this->logger]);
143+
144+
$method = $reflectionClass->getMethod("createSocket");
145+
$method->setAccessible(true);
146+
$res = $method->invokeArgs($transport, [Config::IPV6]);
147+
148+
$this->assertNotFalse($res);
149+
150+
151+
$transport = $this->getMockBuilder(ThriftUdpTransport::class)
152+
->disableOriginalConstructor()
153+
->getMock();
154+
155+
$reflectionClass = new \ReflectionClass($transport);
156+
$method = $reflectionClass->getMethod("setLogger");
157+
$method->setAccessible(true);
158+
$method->invokeArgs($transport, [$this->logger]);
159+
160+
$method = $reflectionClass->getMethod("createSocket");
161+
$method->setAccessible(true);
162+
$res = $method->invokeArgs($transport, [Config::IPV4]);
83163

164+
$this->assertNotFalse($res);
84165
}
85166
}

0 commit comments

Comments
 (0)