Closed WinkelCode closed 4 years ago
Hi! First: What a strange platform you use?!
Why? SO_REUSEPORT
is an Linux option to allow the reuse of the port from the server DIRECTLY after his end. This is especially useful to allow the py-kms server instantly to restart after e.g. a crash or during development cycle. When this socket option is NOT set, it can take up to several minutes until the port is freed by the OS and ready to use again.
Fix? We could add an parameter to disable this option - BUT for that I would need to reproduce it. And I have no idea what or how the platform you use works.
Help to fix! Open up pykms_Server.py
and modify the following line (38):
allow_reuse_address = True
to
allow_reuse_address = False
When this fixes your problem we can proceed to implement a more permanent solution. When not I'll need to dig deeper into our used socket libs...
Looking forward to hear from you!
What a strange platform you use?!
Windows Sandbox is pretty straightforward actually, it's pretty much just an easy to use Windows 10 VM in Hyper-V. It has nice features like copy and pasting stuff into it and being able to communicate with the host (and use the internet) via Hyper-V's vEthernet adapters.
Help to fix! Open up pykms_Server.py and modify the following line (38):
Unfortunately it seems that line is empty and manually adding "allow_reuse_address = False" just results in the same error, I couldn't find "allow_reuse_address" anywhere else in the file either.
I also tried running it with "-u" and "--no-reuse" but it apparently didn't recognize the parameters (I saw these mentioned in file).
Update: It works!
I read the docs (.com) and found out that the correct syntax is connect -u
not just -u
.
Launching with py ./pykms_server.py connect -u
it works!
The only things that I noticed was an error about tzlocal
(which I didn't install and is probably not a big issue) and that nothing got written to the log file (it did when I got the SO_REUSEPORT
error so I think it might be error logging only?)
If this isn't an issue with running it on "normal" Windows, a way to make it automatically launch without port reuse is checking if the current user is "WDAGUtilityAccount" which is the username when running in Windows Sandbox.
Unfortunately it seems that line is empty and manually adding "allow_reuse_address = False" just results in the same error, I couldn't find "allow_reuse_address" anywhere else in the file either.
May bad, I was in the wrong file / lib.
Launching with py ./pykms_server.py connect -u it works!
Congratulations!
that nothing got written to the log file
The default log level is ERROR - so you may need to lower that.
If this isn't an issue with running it on "normal" Windows, a way to make it automatically launch without port reuse is checking if the current user is "WDAGUtilityAccount" which is the username when running in Windows Sandbox.
I'll look into that, but I can't promise anything :grin:
Hey, could you test the following patch for me and confirm it is working (when it does I'll expand the docs and create a PR)?
--- pykms_Server_orig.py 2020-10-07 13:20:20.734492303 +0200
+++ pykms_Server.py 2020-10-07 13:21:11.146097936 +0200
@@ -13,6 +13,7 @@
import socketserver
import queue as Queue
import selectors
+import getpass
from time import monotonic as time
import pykms_RpcBind, pykms_RpcRequest
@@ -524,7 +525,7 @@
log_address = "TCP server listening at %s on port %d" %(srv_config['ip'], srv_config['port'])
if 'listen' in srv_config:
- for l, b, r in zip(srv_config['listen'], srv_config['backlog'], srv_config['reuse']):
+ for l, b, r in zip(srv_config['listen'], srv_config['backlog'], srv_config['reuse'] or getpass.getuser() == 'WDAGUtilityAccount'):
all_address.append(l + (b,) + (r,))
log_address += justify("at %s on port %d" %(l[0], l[1]), indent = 56)
Unfortunately that didn't work either, it simply gave the same error when running it normally but wouldn't even run with connect -u
.
Here is a screenshot from a powershell window where I run a couple commands that should show what is going on, it also confirms the result from "getpass.getuser()" in Windows Sandbox:
Unfortunately that didn't work either, it simply gave the same error when running it normally but wouldn't even run with
connect -u
.Here is a screenshot from a powershell window where I run a couple commands that should show what is going on, it also confirms the result from "getpass.getuser()" in Windows Sandbox:
Right. I'm an idiot - the line is a for loop and I added a bool for checking. I'll give you an other patch in the next days - sorry for that!
@martinsstuff Hey, here is my second attempt - now it should work!
--- pykms_Server_orig.py 2020-10-07 13:20:20.734492303 +0200
+++ pykms_Server.py 2020-10-10 12:50:36.110909231 +0200
@@ -13,6 +13,7 @@
import socketserver
import queue as Queue
import selectors
+import getpass
from time import monotonic as time
import pykms_RpcBind, pykms_RpcRequest
@@ -519,7 +520,7 @@
all_address = [(
srv_config['ip'], srv_config['port'],
(srv_config['backlog_main'] if 'backlog_main' in srv_config else srv_options['backlog']['def']),
- (srv_config['reuse_main'] if 'reuse_main' in srv_config else srv_options['reuse']['def'])
+ (srv_config['reuse_main'] if 'reuse_main' in srv_config else False if getpass.getuser() == 'WDAGUtilityAccount' else srv_options['reuse']['def'])
)]
log_address = "TCP server listening at %s on port %d" %(srv_config['ip'], srv_config['port'])
Awesome, yes that seems to work! It both runs normally and with connect -u
without errors and pykms_Client.py
activated against it with no issues.
Small side note: pykms_Client
by default tries to activate against 0.0.0.0 which just spits out an error about the address not being valid in its context but manually pointing it towards 127.0.0.1 (for this test case) worked.
It might also be a good idea to point out somewhere, as a comment or somewhere else, why this check is done, WDAGUtilityAccount
is usually related to Windows Defender Application Guard and people who don't know this issue here might think it's related to something nefarious. (Well, it's literally for VM detection but for good reasons)
Tested using Python 3.9 and 3.8.6 (x84-64 installers with "add to PATH")
Attempting to run pykms_server.py will result in the error above, I tried manually specifying the local IP (between Windows and Sandbox) but nothing worked, using other random ports didn't either.
This version, although last updated more than a year ago, https://github.com/ThunderEX/py-kms worked without any issues.