11cb0ef41Sopenharmony_ci// Flags: --expose-internals 21cb0ef41Sopenharmony_ci'use strict'; 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciif (common.isWindows) 51cb0ef41Sopenharmony_ci common.skip('Does not support binding fd on Windows'); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst assert = require('assert'); 81cb0ef41Sopenharmony_ciconst dgram = require('dgram'); 91cb0ef41Sopenharmony_ciconst { internalBinding } = require('internal/test/binding'); 101cb0ef41Sopenharmony_ciconst { UDP } = internalBinding('udp_wrap'); 111cb0ef41Sopenharmony_ciconst { UV_UDP_REUSEADDR } = require('os').constants; 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciconst BUFFER_SIZE = 4096; 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci// Test binding a fd. 161cb0ef41Sopenharmony_ci{ 171cb0ef41Sopenharmony_ci function createHandle(reuseAddr, udp4, bindAddress) { 181cb0ef41Sopenharmony_ci let flags = 0; 191cb0ef41Sopenharmony_ci if (reuseAddr) 201cb0ef41Sopenharmony_ci flags |= UV_UDP_REUSEADDR; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci const handle = new UDP(); 231cb0ef41Sopenharmony_ci let err = 0; 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci if (udp4) { 261cb0ef41Sopenharmony_ci err = handle.bind(bindAddress, 0, flags); 271cb0ef41Sopenharmony_ci } else { 281cb0ef41Sopenharmony_ci err = handle.bind6(bindAddress, 0, flags); 291cb0ef41Sopenharmony_ci } 301cb0ef41Sopenharmony_ci assert(err >= 0, String(err)); 311cb0ef41Sopenharmony_ci assert.notStrictEqual(handle.fd, -1); 321cb0ef41Sopenharmony_ci return handle; 331cb0ef41Sopenharmony_ci } 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci function testWithOptions(reuseAddr, udp4) { 361cb0ef41Sopenharmony_ci const type = udp4 ? 'udp4' : 'udp6'; 371cb0ef41Sopenharmony_ci const bindAddress = udp4 ? common.localhostIPv4 : '::1'; 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci let fd; 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci const receiver = dgram.createSocket({ 421cb0ef41Sopenharmony_ci type, 431cb0ef41Sopenharmony_ci }); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci receiver.bind({ 461cb0ef41Sopenharmony_ci port: 0, 471cb0ef41Sopenharmony_ci address: bindAddress, 481cb0ef41Sopenharmony_ci }, common.mustCall(() => { 491cb0ef41Sopenharmony_ci const { port, address } = receiver.address(); 501cb0ef41Sopenharmony_ci // Create a handle to reuse its fd. 511cb0ef41Sopenharmony_ci const handle = createHandle(reuseAddr, udp4, bindAddress); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci fd = handle.fd; 541cb0ef41Sopenharmony_ci assert.notStrictEqual(handle.fd, -1); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci const socket = dgram.createSocket({ 571cb0ef41Sopenharmony_ci type, 581cb0ef41Sopenharmony_ci recvBufferSize: BUFFER_SIZE, 591cb0ef41Sopenharmony_ci sendBufferSize: BUFFER_SIZE, 601cb0ef41Sopenharmony_ci }); 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci socket.bind({ 631cb0ef41Sopenharmony_ci port: 0, 641cb0ef41Sopenharmony_ci address: bindAddress, 651cb0ef41Sopenharmony_ci fd, 661cb0ef41Sopenharmony_ci }, common.mustCall(() => { 671cb0ef41Sopenharmony_ci // Test address(). 681cb0ef41Sopenharmony_ci const rinfo = {}; 691cb0ef41Sopenharmony_ci const err = handle.getsockname(rinfo); 701cb0ef41Sopenharmony_ci assert.strictEqual(err, 0); 711cb0ef41Sopenharmony_ci const socketRInfo = socket.address(); 721cb0ef41Sopenharmony_ci assert.strictEqual(rinfo.address, socketRInfo.address); 731cb0ef41Sopenharmony_ci assert.strictEqual(rinfo.port, socketRInfo.port); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci // Test buffer size. 761cb0ef41Sopenharmony_ci const recvBufferSize = socket.getRecvBufferSize(); 771cb0ef41Sopenharmony_ci const sendBufferSize = socket.getSendBufferSize(); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci // note: linux will double the buffer size 801cb0ef41Sopenharmony_ci const expectedBufferSize = common.isLinux ? 811cb0ef41Sopenharmony_ci BUFFER_SIZE * 2 : BUFFER_SIZE; 821cb0ef41Sopenharmony_ci assert.strictEqual(recvBufferSize, expectedBufferSize); 831cb0ef41Sopenharmony_ci assert.strictEqual(sendBufferSize, expectedBufferSize); 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci socket.send(String(fd), port, address); 861cb0ef41Sopenharmony_ci })); 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci socket.on('message', common.mustCall((data) => { 891cb0ef41Sopenharmony_ci assert.strictEqual(data.toString('utf8'), String(fd)); 901cb0ef41Sopenharmony_ci socket.close(); 911cb0ef41Sopenharmony_ci })); 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci socket.on('error', (err) => { 941cb0ef41Sopenharmony_ci console.error(err.message); 951cb0ef41Sopenharmony_ci assert.fail(err.message); 961cb0ef41Sopenharmony_ci }); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci socket.on('close', common.mustCall()); 991cb0ef41Sopenharmony_ci })); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci receiver.on('message', common.mustCall((data, { address, port }) => { 1021cb0ef41Sopenharmony_ci assert.strictEqual(data.toString('utf8'), String(fd)); 1031cb0ef41Sopenharmony_ci receiver.send(String(fd), port, address); 1041cb0ef41Sopenharmony_ci process.nextTick(() => receiver.close()); 1051cb0ef41Sopenharmony_ci })); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci receiver.on('error', (err) => { 1081cb0ef41Sopenharmony_ci console.error(err.message); 1091cb0ef41Sopenharmony_ci assert.fail(err.message); 1101cb0ef41Sopenharmony_ci }); 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci receiver.on('close', common.mustCall()); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci testWithOptions(true, true); 1161cb0ef41Sopenharmony_ci testWithOptions(false, true); 1171cb0ef41Sopenharmony_ci if (common.hasIPv6) { 1181cb0ef41Sopenharmony_ci testWithOptions(false, false); 1191cb0ef41Sopenharmony_ci } 1201cb0ef41Sopenharmony_ci} 121