nodejs/test/parallel/test-dgram-bind-fd.js

121 lines
3.2 KiB
JavaScript
Raw Normal View History

2022-08-16 11:12:47 +08:00
// Flags: --expose-internals
'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 { internalBinding } = require('internal/test/binding');
const { UDP } = internalBinding('udp_wrap');
const { UV_UDP_REUSEADDR } = require('os').constants;
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);
}
}