Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

socket.bind() + bound address becomes unavailable + query = indefinite hang #19

Open
timbowhite opened this issue Apr 6, 2019 · 2 comments

Comments

@timbowhite
Copy link

timbowhite commented Apr 6, 2019

BTW thanks for this module.

If you socket.bind() to a local address, and then the interface becomes unavailable (ie. network goes down, network interface no longer available, cable unplugged, etc), and you then run a query, the query will hang indefinitely.

Example:

'use strict';

const dnsSocket = require('.')
const socket = dnsSocket({retries: 0, timeout: 5000});

// bind to some local address, 192.168.0.2 in this case, adjust accordingly
new Promise(function (fulfill, reject){
    socket.on('error', reject);
    socket.on('listening', fulfill);
    socket.bind(null, '192.168.0.2');
})
// do something like unplug your network cable
// to make the bound address --> EADDRNOTAVAIL 
.then(function(){
    console.log('socket bound');
    console.log('to reproduce, kill your network connection within the next 5 seconds');
    return new Promise(function(resolve, reject) {
        setTimeout(resolve, 5000);
    });
})
// make a query, it'll hang indefinitely
.then(function(){
    console.log('making socket query, should hang indefinitely');
    return new Promise(function(resolve, reject) {
        socket.query({
              questions: [{
                type: 'A',
                name: 'google.com'
              }]
            },
            53,
            '1.1.1.1',
            function(err, res){
                if (err) return reject(err);
                resolve(res);
            }
        );
    });
})
.then(function(res){
    console.log('got response', res);
    console.log('all done, destroy socket');
    socket.destroy();
})
.catch(function(err){
    console.log('caught error', err);
    socket.destroy();
});

Output:

socket bound
to reproduce, kill your network connection within the next 5 seconds
making socket query, should hang indefinitely

To reproduce, you'll need to:

  1. replace '192.168.0.2' with your local IP address
  2. unplug your network cable/kill your network connection when prompted

I think I see the issue, PR incoming.

@timbowhite
Copy link
Author

timbowhite commented Apr 6, 2019

Nevermind this issue, it can probably be closed :) I didn't wait long enough. dns-socket was still doing retries under the hood and it did eventually time out, even though I did specify 0 retries, 0 is falsey, and thus in the options will still default to 5, i.e:

const socket = dnsSocket({retries: 0, timeout: 5000});

and

this.retries = opts.retries || 0

I'll submit a PR that immediately fails if socket.send() callback has an error, but no worries if you'd prefer not to merge it.

@silverwind
Copy link
Collaborator

Option parsing should be improved to support a 0 value on numeric values. Not sure I agree with immediately failing on socket.send, some errors should be retried, some not, but it's not really easy to distinguish. I'd rather walk on the safe side and retry always.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants