aboutsummaryrefslogtreecommitdiff
path: root/test/parallel/test-dgram-bind-fd.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/parallel/test-dgram-bind-fd.js')
-rw-r--r--test/parallel/test-dgram-bind-fd.js118
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);
+ }
+}