Description
When I open a datagram socket using dgram.createSocket('udp4')
, I'd expect the fd
member of the socket to be set to the socket's fd once it's been properly opened. However, it's never set there, and in order to get the socket's fd, I have to snoop on the private member socket._handle.fd
.
Why is this important to me?
I'm working on a module to implement support for TUNTAP network interfaces as an enabler of node-based virtual networks (think VPNs and VM networks). As a personal goal I'm attempting to write this module with no native code, and it's almost doable by using the ref and ioctl modules.
I say almost because while I'm able to create the TUN/TAP device, I'm not able to get/set options on it (address, broadcast, netmask, mtu) without referencing the private datagram socket API (_handle
).
Example code:
TunTap.prototype.setAddress = function(addr) {
var ifr = new ifreq();
ifr.ref().fill(0);
// the structure of ifreq is really ugly without the C preprocessor :-(
ifr.ifrn_name.buffer.write(this.name);
ifr.ifr_ifru.ifru_addr.sockaddr_in.sin_family = AF_INET;
ifr.ifr_ifru.ifru_addr.sockaddr_in.sin_addr = inet_aton(addr);
var socket = dgram.createSocket('udp4');
// socket isn't open yet, so we bind it to let it open
socket.bind();
socket.on('listening', function() {
try {
//////// vvv PROBLEM IS HERE vvv ////////
var fd = socket.fd;
if (fd == null || fd < 0 ) { // fd is -42 here for some reason...
fd = socket._handle.fd;
}
//////// ^^^ PROBLEM IS HERE ^^^ ////////
ioctl(fd, SIOCSIFADDR, ifr.ref());
this.emit('addr', addr);
} catch (err) {
this.emit('error', 'error setting address on device ' + this.name +
' to ' + addr + ' due to error: ' + err);
}
socket.close();
}.bind(this));
}