http-party / node-portfinder

A simple tool to find an open port or domain socket on the current machine
https://github.com/http-party/node-portfinder
Other
887 stars 95 forks source link

v1.0.0 portfinder no longer works #21

Closed felicienfrancois closed 8 years ago

felicienfrancois commented 8 years ago

Since v1.0.0, On windows 10 + nodejs 5.5, portfinder give me ports that are in use by nodejs http server

indexzero commented 8 years ago

@felicienfrancois pull-request welcome. In the meantime you can safely rely on 0.4.0.

indexzero commented 8 years ago

@eriktrom @stefanpenner looks like this is an unintended side effect of the changes in #20. If you have any cycles to help out it would be greatly appreciated.

eriktrom commented 8 years ago

i'll take a look tonight

@felicienfrancois - any more info you have is greatly appreciated. i dont have much windows usage experience. any steps i can take to repro? is your project open source? thanks

indexzero commented 8 years ago

@eriktrom a great place to start might be to setup Appveyor on a fork. I'm also happy to make you a Github owner if you want to set it up on this repo directly.

stefanpenner commented 8 years ago

I'll take a look at that PR and see if anything jumps out

eriktrom commented 8 years ago

@stefanpenner - just started debugging this - looks like the first two test pass then we get Error: listen EACCES - https://github.com/eriktrom/node-portfinder/pull/1

indexzero commented 8 years ago

I believe this was fixed in #23. Was published in portfinder@1.0.1

dbuhrman commented 8 years ago

I am still experiencing this issue in 1.0.3. Portfinder returns a valid port on OSX, however, same app running on Windows 10 gives a port that is in use by another expressjs app.

eriktrom commented 8 years ago

@dbuhrman - thanks for reporting - can you print your stack trace and versions of everything. Also can you run npm i && npm test inside node-portfinder itself on your machine, that would really help - our tests check for this scenario and run in appveyor but I'm not sure about anything on windows as I don't use it

If the tests pass then i need to borrow your laptop :) (actually I have a branch that logs everything I can give you so I'll should only need your help twice at most, once if the tests fail and give us something good, thanks so much)

eriktrom commented 8 years ago

@dbuhrman - also run this while your at it - while both ports are open on different hosts (if it works in windows, or if you know the equivalent)

netstat -an | grep THEPORT
dbuhrman commented 8 years ago

@eriktrom I can try to run through this evening. I don't have a perfect Windows setup myself. I'm running Windows 10 64 through Parallels (to test an Electron app). npm throws a fit due to some modules not able to compile on 64-bit windows... I'll try to setup an environment for only portfinder tonight and see if I can run the tests and maybe a bit of debugging if I'm feeling bold. :-D

I hope netstat is in Git Bash otherwise I'll try to find the equivalent (while slowly dying inside as I dig into Windows horrible excuse of a CLI).

eriktrom commented 8 years ago

That would be awesome of you - if there is an issue w/ windows this is the only way to fix it - I don't have have windows 10 setup and honestly not enough ram to run it if i did, so thanks again

eriktrom commented 8 years ago

Hey one more thing - parallels has a number of interfaces - make sure to check the box in system preferences or parallels preferences to have it run in host only mode(aka, not shared or bridged, just lonely and isolated)

dbuhrman commented 8 years ago

@eriktrom Tests passed (parallels in host only mode). Additionally, I started my app on port 32773 which should have made one of the tests fail, but all passed anyway. This is all very strange to me, especially since I can't immediately tell the difference between how portfinder's tests setup servers and how the conflicting app (8800 below) is setting up it's server (except the extra wrapper that is express--which simply delegates to http anyway).

Netstat output:

$ netstat -an | grep 8800
  TCP    0.0.0.0:8800           0.0.0.0:0              LISTENING
  TCP    [::]:8800              [::]:0                 LISTENING
eriktrom commented 8 years ago

You found the issue - [::]:0 is not an interface we check - so we bring out the big guns and since he's already on this thread he might press comment before i finish this sentence(lol) but @stefanpenner i guess we should check for [::]:0 as well as [::]:1 - thoughts - he's using parallels so this is not standard but I don't know of a reason not to check it (although I don't know anything about ::0 so that isn't saying much

eriktrom commented 8 years ago

@dbuhrman - btw in the meantime, till I look into it and make sure its okay you can pass the host option of {host: '::0'} and it'll add that interface to the hosts that we check, allowing you to continue your work in peace - thanks very much for contributing, your awesome

dbuhrman commented 8 years ago

Confirmed that config on 1.0.3 fixes my issue on Windows 10.

Thank you everyone for this module. It provides such a simple solution for the general problem of running an Electron app where available ports are unknown.

eriktrom commented 8 years ago

@dbuhrman - no problem - for the record I'm going to just leave the code as it is. With parallels pro you can use prlsrvctl net list to look at your interfaces - i just did and there are too many to account for so we'll just let the end user pass in their host - if that gets annoying, especially with many OS's running, let me know

dbuhrman commented 8 years ago

That's fine with me (workaround seems to work just fine for now), but would like to add that this was originally identified by someone running a host Windows machine, so I fear it may not be limited to Parallels.

Our QA should test this solution Monday (using a Windows laptop) and I can let you know the results. I'm guessing this could all fall apart if someone has a lot of network interfaces on their windows machine? (I have no idea how Windows handles this sort of stuff at all.)

Just as a thought (that I'm voicing out loud): Perhaps using something like https://www.npmjs.com/package/netstats and parsing results to find open ports is an option? Seems like it may be a bit more efficient as well (eliminating overhead of starting and stopping servers), but I also understand that's kinda a fundamental change to your module and probably comes with some significant risk...

eriktrom commented 8 years ago

this was originally identified by someone running a host Windows machine, so I fear it may not be limited to Parallels.

If this is the case, have them run through the same process you did and bring the results on back, we'll see whats up

I'm guessing this could all fall apart if someone has a lot of network interfaces on their windows machine? (I have no idea how Windows handles this sort of stuff at all.)

yes, in theory - but (on first pass of thinking about it) if we take a scenario where someone had 3 interfaces they would also have to have 2 servers running on the same port on 2 different interfaces then when they run portfinder to find the 3rd but pass in the host option of the 3rd open interface, things would be fine - this is what i was alluding to when i printed out the interfaces that parallels provides - there are a lot and you can configure them or add new ones very easily so until I understand the scope of the issue better it's hard to know whether adding a few more default interfaces will help (which i likely would and cause no harm) or if it might not matter as long as a host option is always passed in this multi host scenario. I think we'll add more default hosts based on this, so keep tabs on which ones parallels is using as you work on your electron app - other people will enjoy not having to think about this so its a good feature

Perhaps using something like https://www.npmjs.com/package/netstats and parsing results to find open ports is an option

So this is not a bad idea to be quite honest - does that module work natively on windows and is it installed with every OS by default (netcat that is) or are there some linux distros that require you to install it with root access first - im not sure - although its interesting you bring that up b/c its unique and not clouded by what was already here before we added host checking - and its is remarkably simpler (amazing what fresh eyes will do for perspective) - that said like you mention, maybe not reliable - couldn't say

anyway - come back with the ideal hosts to check for in your setup and I think we'll add them. I'm not sure what that parallels command will print out when more than one VM is booted, if its creating virtual interfaces for each VM and their predictable then yeah lets add them (i think ::0, ::1 and ::2 might be the answer, we'll see)

dbuhrman commented 8 years ago

Will do on hosts. I really dislike how unpredictable this seems to be on Windows. Just a thought (now understanding more of the root cause), maybe add a config option to turn off host checking (to more accurately simulate how we are about to start our express server)? Or to further this idea, but maybe a step too far, give a way to override how the 'test' server is started, this way the user could give portfinder the exact server they want to setup after a port is found.

On the netstats module: I do believe netstat has come with Windows since at least Windows XP (maybe earlier). That particular module (which was a 2 second search on my end--so maybe not the best that exists) appears to use netstat for Windows and lsof for anything else. Looking at the code, it simply runs the command through child_process.exec and dumps the results. IMO it should at least normalize the output, otherwise I don't really see much value (just a wrapper around running a command--which I'd then have to analyze the platform I'm on to understand the results anyway...).

Sorry for the continuous comments, just trying to throw ideas out there. In the end, if it works, or I can make it work, I'm happy (even if that means continuing to add ::${x} to my hosts list). :D

eriktrom commented 8 years ago

all good with the comments

try netcat on a native window laptop - the ember team added the hosts feature to handle ember-cli's live reload server not working in a corporate environment where the laptop and network we're controlled meaning the network card was swapped and bound to by the company - which is just like you'd get if you choose bridge mode in the output below (i believe)

$ prlsrvctl net list

Network ID        Type      Bound To
Shared            shared  vnic0
NAT server:

Host-Only         host-only  vnic1
vagrant-vnet0     host-only  vnic2
Wi-Fi (en0)       bridged   en0
en2 (en2)         bridged   en2
p2p0 (p2p0)       bridged   p2p0
awdl0 (awdl0)     bridged   awdl0
Thunderbolt Bri~  bridged   bridge0
Parallels Share~  bridged   vnic0
Parallels Host-~  bridged   vnic1
vnic2 (vnic2)     bridged   vnic2
Default           bridged   FF:FF:FF:FF:FF:FF

If you take that concept and realize your work computer might have the same thing going on its hard to identify windows as the culprit or something else. (parallels actually sheds more light on the topic than I could explain to you otherwise - when no host is passed to the node net module, it uses undefined which resolves to different things on different os's, node versions and network adapters, which was a fun game)

You can turn off host checking by installing the last version before 1.0 to try it out - i think it was v0.6

Finally regarding switching to the netstats module - if i we're to write the lib today I would definately try it - but I broke this module in 1.0, someone else broke it in 1.1 and in 1.2 I allowed another bug to ship b/c I was unsure of myself and so for a while things we're rocky - i'd hate to disrupt the peace - quite a few upstream modules use this lib

that all said, we can loop pretty fast - unless you find hosts that are higher ::2 it's hard to notice and b/c its a dev tool its not a big deal really (a production server would be different of course)

anyway, thanks for helping out - hopefully that adds extra context - i'd love to support the VM use case as its something I hadn't thought of and if windows ends up being an issue that we have to fix for sure.

(also check out the windows network adapters inside a native windows machine - see how many there are and what their settings are - I think you understand this pretty well and the rest should make sense as you find the answer - which will improve the lib so again thanks)