redis
redis copied to clipboard
Command-line --port argument does not work for some arguments
Hi,
For some reason, redis-server --port N does not work for some N, and this seems to be for a large (and seemingly arbitrary) set of N values that don't appear to have correlation with what my system already has open. I get bind: An operation was attempted on something that is not a socket
as follows:
> redis-server --port 2055
[14520] 31 May 03:28:12.636 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
[14520] 31 May 03:28:12.636 # Redis version=5.0.9, bits=64, commit=9414ab9b, modified=0, pid=14520, just started
[14520] 31 May 03:28:12.636 # Configuration loaded
[14520] 31 May 03:28:12.646 # Could not create server TCP listening socket *:2055: bind: An operation was attempted on something that is not a socket.
> redis-server --port 2056
[8772] 31 May 03:28:14.799 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
[8772] 31 May 03:28:14.799 # Redis version=5.0.9, bits=64, commit=9414ab9b, modified=0, pid=8772, just started
[8772] 31 May 03:28:14.805 # Configuration loaded
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.9 (9414ab9b/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 2056
| `-._ `._ / _.-' | PID: 8772
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
[8772] 31 May 03:28:14.807 # Server initialized
[8772] 31 May 03:28:14.807 * Ready to accept connections
[8772] 31 May 03:28:15.475 # User requested shutdown...
[8772] 31 May 03:28:15.475 # Redis is now ready to exit, bye bye...
I haven't had a chance to debug it through compiling the code, but one curiosity appears to be be that ioctlsocket(x, FIONBIO, ...)
is called with x
being both 3
and 4
, both of which result in WSAENOTSOCK
(which is not surprising, given they don't look like valid handles). However, this appears to occur for both working ports as well as broken ports, so I'm not sure if it's actually related. But this problem comes up for both version 4 and version 5. Would you have any guesses as to why? Thank you!
It seems it gives this not-so-meaningful error message when a given port cannot be bound as it is already in use. You can test it by running redis-server.exe --port 2055
twice:
(the message is in Polish, but it is the same error).
I will have a look though if this could be improved to show what is really going on there (port already in use).
Thanks! I think that's not the cause here, though it does show the same error in that case. This happens to too many ports for me for them all to be in use. And I can indeed confirm they're not:
> redis-server.exe --port 2055
[3564] 31 May 06:07:42.424 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
[3564] 31 May 06:07:42.424 # Redis version=5.0.9, bits=64, commit=9414ab9b, modified=0, pid=3564, just started
[3564] 31 May 06:07:42.424 # Configuration loaded
[3564] 31 May 06:07:42.439 # Could not create server TCP listening socket *:2055: bind: An operation was attempted on something that is not a socket.
> netstat -a -n | findstr 2055
>
That said, I'm not sure if this is actually a problem with this repo, or with Redis itself, or with the Windows kernel somehow. Because I feel like I saw something similar on WSL. Though the ioctlsocket
I traced in Windows didn't really make sense either, so maybe there are multiple problems?
There is this RFDMap feature of mapping file descriptors to files/sockets that is kicking in here, so maybe it is passing not the right structure to bind
. Anyway, one would expect to get a WSAEADDRINUSE
instead of WSAENOTSOCK
in case port is already in use, will investigate that - thanks for reporting this!
So I got a chance to look into this, and it seems there are indeed 2 issues. One is in anetListen
:
if (bind(s,sa,len) == -1) {
anetSetError(err, "bind: %s", IF_WIN32(wsa_strerror(errno), strerror(errno)));
It's checking errno
for some reason when in fact it should be checking WSAGetLastError()
.
The actual error is, in fact, WSAEACCES
. For some reason, I can't bind to some ports (like 2048
) on my system with AF_INET6
, but I can with AF_INET
. It appears these ports are reserved ("excluded") on my machine, but I have no idea why:
> netsh int ipv6 show excludedportrange tcp
Protocol tcp Port Exclusion Ranges
Start Port End Port
---------- --------
<snip>
1956 2055
<snip>
Is there a way to force IPv4-only with Redis? If not, should there be something to allow that?
For me it shows only port 5357
. As for falling back to IPv4 - I think I've seen something that should try it, but perhaps it works differently on Windows - will check that, too.
Interesting. It turns out this is due to Hyper-V. Uninstalling the feature removes the port reservations.