diff options
Diffstat (limited to 'test/parallel/test-dgram-bind-fd.js')
-rw-r--r-- | test/parallel/test-dgram-bind-fd.js | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/test/parallel/test-dgram-bind-fd.js b/test/parallel/test-dgram-bind-fd.js new file mode 100644 index 0000000000..c4a80abb92 --- /dev/null +++ b/test/parallel/test-dgram-bind-fd.js @@ -0,0 +1,118 @@ +'use strict'; +const common = require('../common'); +if (common.isWindows) + common.skip('Does not support binding fd on Windows'); + +const assert = require('assert'); +const dgram = require('dgram'); +const { UDP } = process.binding('udp_wrap'); +const { UV_UDP_REUSEADDR } = process.binding('constants').os; + +const BUFFER_SIZE = 4096; + +// Test binding a fd. +{ + function createHandle(reuseAddr, udp4, bindAddress) { + let flags = 0; + if (reuseAddr) + flags |= UV_UDP_REUSEADDR; + + const handle = new UDP(); + let err = 0; + + if (udp4) { + err = handle.bind(bindAddress, 0, flags); + } else { + err = handle.bind6(bindAddress, 0, flags); + } + assert(err >= 0, String(err)); + assert.notStrictEqual(handle.fd, -1); + return handle; + } + + function testWithOptions(reuseAddr, udp4) { + const type = udp4 ? 'udp4' : 'udp6'; + const bindAddress = udp4 ? common.localhostIPv4 : '::1'; + + let fd; + + const receiver = dgram.createSocket({ + type, + }); + + receiver.bind({ + port: 0, + address: bindAddress, + }, common.mustCall(() => { + const { port, address } = receiver.address(); + // Create a handle to reuse its fd. + const handle = createHandle(reuseAddr, udp4, bindAddress); + + fd = handle.fd; + assert.notStrictEqual(handle.fd, -1); + + const socket = dgram.createSocket({ + type, + recvBufferSize: BUFFER_SIZE, + sendBufferSize: BUFFER_SIZE, + }); + + socket.bind({ + port: 0, + address: bindAddress, + fd, + }, common.mustCall(() => { + // Test address(). + const rinfo = {}; + const err = handle.getsockname(rinfo); + assert.strictEqual(err, 0); + const socketRInfo = socket.address(); + assert.strictEqual(rinfo.address, socketRInfo.address); + assert.strictEqual(rinfo.port, socketRInfo.port); + + // Test buffer size. + const recvBufferSize = socket.getRecvBufferSize(); + const sendBufferSize = socket.getSendBufferSize(); + + // note: linux will double the buffer size + const expectedBufferSize = common.isLinux ? + BUFFER_SIZE * 2 : BUFFER_SIZE; + assert.strictEqual(recvBufferSize, expectedBufferSize); + assert.strictEqual(sendBufferSize, expectedBufferSize); + + socket.send(String(fd), port, address); + })); + + socket.on('message', common.mustCall((data) => { + assert.strictEqual(data.toString('utf8'), String(fd)); + socket.close(); + })); + + socket.on('error', (err) => { + console.error(err.message); + assert.fail(err.message); + }); + + socket.on('close', common.mustCall(() => {})); + })); + + receiver.on('message', common.mustCall((data, { address, port }) => { + assert.strictEqual(data.toString('utf8'), String(fd)); + receiver.send(String(fd), port, address); + process.nextTick(() => receiver.close()); + })); + + receiver.on('error', (err) => { + console.error(err.message); + assert.fail(err.message); + }); + + receiver.on('close', common.mustCall(() => {})); + } + + testWithOptions(true, true); + testWithOptions(false, true); + if (common.hasIPv6) { + testWithOptions(false, false); + } +} |