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

dgram: handle default address case when offset and length are specified #5407

Closed
wants to merge 1 commit into from

Conversation

mcollina
Copy link
Member

Pull Request check-list

  • Does make -j8 test (UNIX) or vcbuild test nosign (Windows) pass with
    this change (including linting)?
  • Is the commit message formatted according to CONTRIBUTING.md?
  • If this change fixes a bug (or a performance problem), is a regression
    test (or a benchmark) included?
  • Is a documentation update included (if this change modifies
    existing APIs, or introduces new ones)?

Affected core subsystem(s)

dgram

Description of change

Fixes a regression introduced by #4374 and released in 5.7.0.
Adds a new test to avoid similar issue in the future.

Fixes: #5398

Please review @jasnell @saghul @mafintosh @Fishrock123 @rvagg

@mcollina mcollina added the dgram Issues and PRs related to the dgram subsystem / UDP. label Feb 24, 2016
@mcollina mcollina added this to the 5.7.1 milestone Feb 24, 2016
@mcollina mcollina mentioned this pull request Feb 24, 2016
3 tasks
@@ -294,8 +302,7 @@ Socket.prototype.send = function(buffer,
callback) {
var self = this;

// same as arguments.length === 5 || arguments.length === 6
if (address) {
if (address || port && !isFunction(port)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've given up on util.is*(), just do a typeof instead

@mcollina
Copy link
Member Author

@rvagg updated! thanks!

@mcollina mcollina self-assigned this Feb 24, 2016
@@ -294,8 +301,7 @@ Socket.prototype.send = function(buffer,
callback) {
var self = this;

// same as arguments.length === 5 || arguments.length === 6
if (address) {
if (address || port && typeof port !== 'function') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, a very minor nit but I'd prefer brackets around the && section to be explicit although I don't know if we've set precedent elsewhere in the code

@rvagg
Copy link
Member

rvagg commented Feb 24, 2016

lgtm

@evanlucas
Copy link
Contributor

LGTM

@mcollina
Copy link
Member Author

@rvagg nit fixed. I'll wait for CI to come back online before merging.

@mafintosh can you please check if this solves the problem for you?

@Fishrock123
Copy link
Contributor

linking to release proposal: #5400

@mcollina
Copy link
Member Author

@mcollina
Copy link
Member Author

I have a failure on windows: https://ci.nodejs.org/job/node-test-binary-windows/1193/RUN_SUBSET=3,VS_VERSION=vs2013,label=win2008r2/tapTestReport/test.tap-49/

It's a timeout issue, maybe I should just increate the timeout?
I think it's a flaky one, as it happens only on some envs, I'll retry.

New run, without any changes: https://ci.nodejs.org/job/node-test-pull-request/1744/

@mcollina
Copy link
Member Author

Ok, it is definitely an issue on windows 2008r2 and windows 2012r2. Any idea? BTW, this case was not covered by unit tests before, so it might well be the default address was not working on windows.

@santigimeno
Copy link
Member

@mcollina what happens if you remove the timer from the test?

@mcollina
Copy link
Member Author

I've increased the timeout by 10 times, let's see how it goes: https://ci.nodejs.org/job/node-test-pull-request/1750/.

@mcollina
Copy link
Member Author

Ok, it seems this is problematic on windows. I'll check tomorrow on my windows box (or is there anybody that can help). Given there were no unit tests for this case before, it's possible that we have this bug on Windows even on previous releases - I'll check that as well.

@mcollina
Copy link
Member Author

Confirmed, this does not work on windows at all (tested quickly in v4.2.4):

'use strict'

const dgram = require('dgram')
const socket = dgram.createSocket('udp4')
const port = 2222
const assert = require('assert')
const buf = new Buffer('hello')

socket.on('listening', () => {
  socket.send(buf, 0, buf.length, port)
})

const timer = setTimeout(() => {
  assert.fail('no message')
}, 1000)

socket.on('message', (rec) => {
  assert.ok(rec.equals(buf), 'buffer do not matches')
  clearTimeout(timer)
  socket.close()
})

socket.bind(port)

@mcollina
Copy link
Member Author

I might need some help to get this fixed and released soonish. @nodejs/platform-windows can you help me out (also the windows fix might need backport to LTS)?

@rvagg
Copy link
Member

rvagg commented Feb 26, 2016

@saghul @indutny perhaps you could weight in as well?

If this doesn't work on Windows, perhaps it shouldn't be an officially supported piece of functionality then? Sounds like it was supported unintentionally in the first place.

@saghul
Copy link
Member

saghul commented Feb 26, 2016

I can take a look, but before I do, can you try the following? Bind to 127.0.0.1 instead of letting the autobind magic work.

Also, the target address should be specified IMHO. It may work somewhere by accident, but what does it mean to send a datagram to port 2222? As in, port 2222 of what IP address?

@saghul
Copy link
Member

saghul commented Feb 26, 2016

I took a quick peek, and the internal lookup thing sets the address to '0.0.0.0' if undefined, that's not going to fly on all platforms, I'm afraid.

@mcollina
Copy link
Member Author

@saghul binding to 127.0.0.1 does not work either.

Also, the target address should be specified IMHO. It may work somewhere by accident, but what does it mean to send a datagram to port 2222? As in, port 2222 of what IP address?

I completely agree with you, but in the docs we support address to be optional (IMHO it should not be):

If the address is not specified or is an empty string, '0.0.0.0' or '::0' will be used instead

@mafintosh this means you had a bug in your library on windows systems anyway.

We have an accidental behavior on which modules rely on, so I think we should keep supporting that, and maybe look for deprecating the default address (in dgram, net, tls, http, ...) in the next semver-major cycle for outgoing connections/messages.

How can I rewrite the tests so that they are run only on Linux/Mac? Should I just add an if at the beginning and early return if windows?

@saghul
Copy link
Member

saghul commented Feb 26, 2016

I completely agree with you, but in the docs we support address to be optional (IMHO it should not be):

The docs actually say this: "It is possible, depending on the network configuration, that these defaults may not work; accordingly, it is best to be explicit about the destination address. " so, I suggest you write the test by passing the address and no rely on it being undefined.

@mcollina
Copy link
Member Author

@saghul the bug we are trying to address here is that I (unintentionally) broke the old "half-broken" behavior:

It is possible, depending on the network configuration, that these defaults may not work; accordingly, it is best to be explicit about the destination address.

To avoid any regressions, I am adding a unit test, because there was no one before.
I will update the unit test and returning early if windows.

@mcollina
Copy link
Member Author

@mcollina
Copy link
Member Author

Tests passes, I've added a bit more of comments around it.

Can I get a bunch of LGTM so we can land this?

@mcollina
Copy link
Member Author

cc @silverwind

@silverwind
Copy link
Contributor

LGTM as a short-term fix but not too happy about the Windows skip, it should be researched further.

@mcollina
Copy link
Member Author

Landed in 725ffdb

@mcollina mcollina closed this Feb 28, 2016
Fishrock123 referenced this pull request Mar 2, 2016
Fixes a regression introduced by: #4374.
Adds a new test to avoid similar issue in the future.
The test is disabled on windows, because this feature never worked
there.

Fixes: #5398
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Fishrock123 added a commit that referenced this pull request Mar 2, 2016
Notable changes:

* governance: The Core Technical Committee (CTC) added four new members
to help guide Node.js core development: Evan Lucas, Rich Trott, Ali
Ijaz Sheikh and Сковорода Никита Андреевич (Nikita Skovoroda).

* openssl: Upgrade from 1.0.2f to 1.0.2g (Ben Noordhuis)
#5507
  - Fix a double-free defect in parsing malformed DSA keys that may
potentially be used for DoS or memory corruption attacks. It is likely
to be very difficult to use this defect for a practical attack and is
therefore considered low severity for Node.js users. More info is
available at https://www.openssl.org/news/vulnerabilities.html#2016-0705
  - Fix a defect that can cause memory corruption in certain very rare
cases relating to the internal `BN_hex2bn()` and `BN_dec2bn()`
functions. It is believed that Node.js is not invoking the code paths
that use these functions so practical attacks via Node.js using this
defect are _unlikely_ to be possible. More info is available at
https://www.openssl.org/news/vulnerabilities.html#2016-0797
  - Fix a defect that makes the CacheBleed Attack
(https://ssrg.nicta.com.au/projects/TS/cachebleed/) possible. This
defect enables attackers to execute side-channel attacks leading to the
potential recovery of entire RSA private keys. It only affects the
Intel Sandy Bridge (and possibly older) microarchitecture when using
hyper-threading. Newer microarchitectures, including Haswell, are
unaffected. More info is available at
https://www.openssl.org/news/vulnerabilities.html#2016-0702

* Fixed several regressions that appeared in v5.7.0:
  - path.relative():
    - Output is no longer unnecessarily verbose (Brian White)
#5389
    - Resolving UNC paths on Windows now works correctly (Owen Smith)
#5456
    - Resolving paths with prefixes now works correctly from the root
directory (Owen Smith) #5490
  - url: Fixed an off-by-one error with `parse()` (Brian White)
#5394
  - dgram: Now correctly handles a default address case when offset and
length are specified (Matteo Collina)
#5407

PR-URL: #5464
Fishrock123 added a commit to Fishrock123/node that referenced this pull request Mar 2, 2016
Notable changes:

* governance: The Core Technical Committee (CTC) added four new members
to help guide Node.js core development: Evan Lucas, Rich Trott, Ali
Ijaz Sheikh and Сковорода Никита Андреевич (Nikita Skovoroda).

* openssl: Upgrade from 1.0.2f to 1.0.2g (Ben Noordhuis)
nodejs#5507
  - Fix a double-free defect in parsing malformed DSA keys that may
potentially be used for DoS or memory corruption attacks. It is likely
to be very difficult to use this defect for a practical attack and is
therefore considered low severity for Node.js users. More info is
available at https://www.openssl.org/news/vulnerabilities.html#2016-0705
  - Fix a defect that can cause memory corruption in certain very rare
cases relating to the internal `BN_hex2bn()` and `BN_dec2bn()`
functions. It is believed that Node.js is not invoking the code paths
that use these functions so practical attacks via Node.js using this
defect are _unlikely_ to be possible. More info is available at
https://www.openssl.org/news/vulnerabilities.html#2016-0797
  - Fix a defect that makes the CacheBleed Attack
(https://ssrg.nicta.com.au/projects/TS/cachebleed/) possible. This
defect enables attackers to execute side-channel attacks leading to the
potential recovery of entire RSA private keys. It only affects the
Intel Sandy Bridge (and possibly older) microarchitecture when using
hyper-threading. Newer microarchitectures, including Haswell, are
unaffected. More info is available at
https://www.openssl.org/news/vulnerabilities.html#2016-0702

* Fixed several regressions that appeared in v5.7.0:
  - path.relative():
    - Output is no longer unnecessarily verbose (Brian White)
nodejs#5389
    - Resolving UNC paths on Windows now works correctly (Owen Smith)
nodejs#5456
    - Resolving paths with prefixes now works correctly from the root
directory (Owen Smith) nodejs#5490
  - url: Fixed an off-by-one error with `parse()` (Brian White)
nodejs#5394
  - dgram: Now correctly handles a default address case when offset and
length are specified (Matteo Collina)
nodejs#5407

PR-URL: nodejs#5464
mcollina added a commit to mcollina/node that referenced this pull request Mar 4, 2016
In net we default to 'localhost' as the default address for connect.
Not doing the same on dgram is confusing, because sending to 0.0.0.0
works on Linux/OS X but not on Windows. Defaulting that to 127.0.0.1 /
::1 addresses that.

Related: nodejs#5407
Related: nodejs#5398

Fixes: nodejs#5487
mcollina added a commit that referenced this pull request Mar 5, 2016
In net we default to 'localhost' as the default address for connect.
Not doing the same on dgram is confusing, because sending to 0.0.0.0
works on Linux/OS X but not on Windows. Defaulting that to 127.0.0.1 /
::1 addresses that.

Related: #5407
Related: #5398
Fixes: #5487
PR-URL: #5493
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
Fishrock123 pushed a commit that referenced this pull request Mar 8, 2016
In net we default to 'localhost' as the default address for connect.
Not doing the same on dgram is confusing, because sending to 0.0.0.0
works on Linux/OS X but not on Windows. Defaulting that to 127.0.0.1 /
::1 addresses that.

Related: #5407
Related: #5398
Fixes: #5487
PR-URL: #5493
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
Fishrock123 pushed a commit that referenced this pull request Mar 8, 2016
In net we default to 'localhost' as the default address for connect.
Not doing the same on dgram is confusing, because sending to 0.0.0.0
works on Linux/OS X but not on Windows. Defaulting that to 127.0.0.1 /
::1 addresses that.

Related: #5407
Related: #5398
Fixes: #5487
PR-URL: #5493
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
MylesBorins referenced this pull request Mar 11, 2016
Fixes a regression introduced by: #4374.
Adds a new test to avoid similar issue in the future.
The test is disabled on windows, because this feature never worked
there.

Fixes: #5398
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dgram Issues and PRs related to the dgram subsystem / UDP.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dgram: socket.send without address fails with weird error on 5.7
8 participants