Skip to content

Commit 848b32f

Browse files
committed
Fix SOCKS5 client receiving destination hostnames
1 parent b08dcd1 commit 848b32f

2 files changed

Lines changed: 40 additions & 4 deletions

File tree

src/Client.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,15 +349,15 @@ private function handleSocks5(ConnectionInterface $stream, $host, $port, StreamR
349349
if ($data['type'] === 0x01) {
350350
// IPv4 address => skip IP and port
351351
return $reader->readLength(6);
352-
} else if ($data['type'] === 0x03) {
352+
} elseif ($data['type'] === 0x03) {
353353
// domain name => read domain name length
354354
return $reader->readBinary(array(
355355
'length' => 'C'
356-
))->then(function ($data) use ($that) {
356+
))->then(function ($data) use ($reader) {
357357
// skip domain name and port
358-
return $that->readLength($data['length'] + 2);
358+
return $reader->readLength($data['length'] + 2);
359359
});
360-
} else if ($data['type'] === 0x04) {
360+
} elseif ($data['type'] === 0x04) {
361361
// IPv6 address => skip IP and port
362362
return $reader->readLength(18);
363363
} else {

tests/ClientTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,42 @@ public function testEmitSocks5DataErrorDuringSessionWillRejectConnection()
244244
$promise->then(null, $this->expectCallableOnceWithExceptionCode(SOCKET_ECONNREFUSED));
245245
}
246246

247+
public function testEmitSocks5DataInvalidAddressTypeWillRejectConnection()
248+
{
249+
$stream = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->setMethods(array('write', 'close'))->getMock();
250+
$stream->expects($this->once())->method('close');
251+
252+
$promise = \React\Promise\resolve($stream);
253+
254+
$this->connector->expects($this->once())->method('connect')->with('127.0.0.1:1080?hostname=google.com')->willReturn($promise);
255+
256+
$this->client = new Client('socks5://127.0.0.1:1080', $this->connector);
257+
258+
$promise = $this->client->connect('google.com:80');
259+
260+
$stream->emit('data', array("\x05\x00" . "\x05\x00\x00\x00"));
261+
262+
$promise->then(null, $this->expectCallableOnceWithExceptionCode(SOCKET_EBADMSG));
263+
}
264+
265+
public function testEmitSocks5DataHostnameAddressWillResolveConnection()
266+
{
267+
$stream = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->setMethods(array('write', 'close'))->getMock();
268+
$stream->expects($this->never())->method('close');
269+
270+
$promise = \React\Promise\resolve($stream);
271+
272+
$this->connector->expects($this->once())->method('connect')->with('127.0.0.1:1080?hostname=google.com')->willReturn($promise);
273+
274+
$this->client = new Client('socks5://127.0.0.1:1080', $this->connector);
275+
276+
$promise = $this->client->connect('google.com:80');
277+
278+
$stream->emit('data', array("\x05\x00" . "\x05\x00\x00\x03\x0Agoogle.com\x00\x50"));
279+
280+
$promise->then($this->expectCallableOnce());
281+
}
282+
247283
public function provideConnectionErrors()
248284
{
249285
return array(

0 commit comments

Comments
 (0)