sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

For all the help you need with Armagetron!
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

after spending more hours putting echo commands just about everywhere to follow the path of the functions I think I have come up with a solution that should work but I need a little help

in src/tron/gGame.cpp function sg_HostGame() I think that shutting down the network just before the server talks to the masters should allow it to re-initialise with the correct port

I added sn_BasicNetworkSystem.Shutdown() just before it talks to the master with nServerInfo::TellMasterAboutMe( gServerBrowser::CurrentMaster() ); but it doesnt seem to do anything

Looking through the network docs I see in layer 1 a function void ANET_Shutdown (void);

I think I need this but I havent figured out how to add it, If anyone can help me add ANET_Shutdown (); into the code please do because I think this will finally solve the server_port issue

Thanks

Code: Select all

void sg_HostGame()
{
        {
                // create a game to check map once
                tJUST_CONTROLLED_PTR< gGame > game = tNEW(gGame);
                game->Verify();
        }


        // shut the network down to fix server_port issue
        con << "*** shutting down network ***\n";
        sn_BasicNetworkSystem.Shutdown();

        if (sg_TalkToMaster)
                nServerInfo::TellMasterAboutMe( gServerBrowser::CurrentMaster() );

        sn_SetNetState(nSERVER);
Image Image Image Image
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

its not going to work :(
i downloaded the source code for 0.2.7 which does have ANET_Shutdown ( thanks to nelg for finding that out ), it does exactly what sn_BasicNetworkSystem.Shutdown does ie sets listen to false and closes control socket

hmmm

i need to see whats going on with these ports, I still cant understand why running scripts from armagetron would cause this issue in the first place
Image Image Image Image
User avatar
aP|Nelg
Match Winner
Posts: 621
Joined: Wed Oct 22, 2014 10:22 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by aP|Nelg »

ArmagetronAd wrote:[0] Command HUD_CACHE_THRESHOLD unknown.
[0]
[0] Bound socket to *.*.*.*:54021.
[0] Bound socket to *.*.*.*:4565.
[0] Setting CYCLE_BRAKE_DEPLETE (Group: Annoying) deviates from its default value; clients older than 0.2.5.0 may experience problems.
[0] Ping charity changed from 0 to 500.
[0] Nobody there. Taking a nap...
[0] Timestamp: 2020/05/25 20:13:20
[0] Closing socket bound to *.*.*.*:4565
[0] Bound socket to *.*.*.*:4565.
SPAWN_SCRIPT notascript
[0] Launching external command '/home/armagetron/.armagetronad-ap-dedicated/scripts/notascript'...
execve: Permission denied
[0] notascript : [0] Closing socket bound to *.*.*.*:4565
[0] Command [0] unknown.
[0] notascript : [0] Closing socket bound to *.*.*.*:54021
[0] Command [0] unknown.
This might be helpful: I've noticed that if the script (or some other file in that directory) exists but isn't executable, the server somehow interprets the process as sending "Closing socket bound" console output
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

thanks nelg, I just tested that and yeah the server just shuts down its sockets and freezes leaving all players in limbo driving around a dead arena

something very odd going on here, its very interesting

I will look deeper
Image Image Image Image
User avatar
Z-Man
God & Project Admin
Posts: 11585
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Z-Man »

aP|Nelg wrote: Tue May 26, 2020 1:15 amThis might be helpful: I've noticed that if the script (or some other file in that directory) exists but isn't executable, the server somehow interprets the process as sending "Closing socket bound" console output
Oi, that's interesting. In debug mode, I also get "Memory leak detected" and other shutdown messages... I think it's trying to shut down the server and interpreting its own output as input? Or something weirder.
Oh. Ooooh. No, precisely that. We use fork(), one leg keeps executing the game server, the other the script... when the script fails or is done, it calls exit(1).. all the wile feeding its output into the input of the server.

That fork() there is the source of your socket problems, too. The child process shares ownership of the sockets the parent opened, if I understand correctly. So the process executing your script is, in fact, holding your socket open and sabotaging the reopening. I think the right thing to do for the child process would be to drop the sockets as soon as it starts, and the standard input after the script executed/failed, and then kill itself as quietly as possible. exit(-1) apparently does not do that.
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

thanks z-man for understanding the problem

I understand what you just said but for me to actually implement it is another thing entirely lol

i will try my best but if you feel like fixing it well that'll be cool too :)

im curious but that quick hack system call thing i posted previously doesnt do any fork stuff but I still had the issue of the server port increasing after everyone leaves the game

code from previous post

Code: Select all

// myscript command WARNING: EXTREMELY DANGEROUS DONT TRY THIS AT HOME
static void myScript( std::istream & s )
{
        tString command;
        command.ReadLine(s);
        system( command );
}

static tConfItemFunc myScript_conf( "MY_SCRIPT", myScript );
Image Image Image Image
User avatar
Z-Man
God & Project Admin
Posts: 11585
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Z-Man »

Galaxip wrote: Tue May 26, 2020 11:42 pm I understand what you just said but for me to actually implement it is another thing entirely lol
Heh, I'm stumped as well. I see several approaches:
1. Keep things basically as they are now, but before calling the script in the forked process, SILENTLY close all sockets and files other than the standard input/output (I don't think we have any), and when you shut down after the script is done, do so without side effects.
The 'without side effects' is the tricky bit, this is C++ and we make use of static objects, they do work in their destructors. Apparently even if you call exit(-1).
2. fork() earlier. Do a preemptive fork() of a single script process right at the start of main() so it doesn't know anything about sockets or the game state. Communicate with that over input/output streams. This is the clean option, but also tons of work. There are still the static objects with init/exit side effects to worry about, but I think at this stage they don't pose problems.
3. look for a different way to spawn a subprocess that does not involve fork(), but still allows communication. All we need to control in the subprocess are the input/output pipelines and environment variables.

To patch your problem, I'd go with 1). Disable console output (is it already possible? If not, we're in the right file, a static flag could do the job), kill off the network sockets (Do we have direct access from this point? We're in the render subsystem for some reason...), worry about the exit problems later.
For a better solution, I'd research 3) first, but grudgingly settle for option 2) if nothing comes up.

Edit: Ah, fork() followed by exec...() should be right thing already. exec... completely replaces the current process, meaning there are no shutdown side effects. Only in the investigated case, exec... fails. We should not call exit(), then, but another exec...() that's bound to succeed. Still, sockets probably need silent closing. I don't know why this is required even in the success case.
Galaxip wrote: Tue May 26, 2020 11:42 pmim curious but that quick hack system call thing i posted previously doesnt do any fork stuff but I still had the issue of the server port increasing after everyone leaves the game
The man page of system() says it is using fork(), so you're just hiding the call.
User avatar
Z-Man
God & Project Admin
Posts: 11585
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Z-Man »

Ah, everything is going to be all right. We don't have to do anything drastic, the general procedure is perfectly safe, just the details are a bit off. We have two problems here:
1. The exit(-1) call does not immediately exit, it calls all C++ static destructors. Those are registered via atexit() or on_exit(), the implementation can pick which. Check out the manpage of exit ('man 2 exit') what you can do there.

2. Your socket problem. execve() completely replaces the current process in memory. You would think that this means it also closes all open file descriptors, that includes sockets and pipes, before the replacement, because afterwards, it has lost all references to them and can't do that any more. But if it did that, communicating with the script would be impossible, because standard input and output would also be lost. Luckily, that does not mean we have to manually close the sockets before calling execve(). Instead, we can pass a flag to the socket() call in nSocket.cpp to have them closed for us later automatically. Relevant scripture:
https://stackoverflow.com/questions/612 ... tl-flag-do
https://www.man7.org/linux/man-pages/man2/socket.2.html (or 'man 2 socket')

Looking forward to your merge request! Be sure to reference https://gitlab.com/armagetronad/armaget ... /issues/13 in it.
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

I did look at exec stuff before but i think i misunderstood what it was telling me and thought it would shut down armagetron lol
i just have a basic understanding of c++ and get lost in the really deep stuff

the other thing i had considered whats having an external spawnscript.sh started before the server is started that listens for input commands to spawn so possibly doesnt affect the servers internal workings

ive looked at so much code lately my brain hurts, I need a break

gonna play some armagetron and chill for a bit and come back to this maybe in a week

thanks again guys for your help, I will revisit this
Image Image Image Image
User avatar
Z-Man
God & Project Admin
Posts: 11585
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Z-Man »

Galaxip wrote: Wed May 27, 2020 10:31 pm I did look at exec stuff before but i think i misunderstood what it was telling me and thought it would shut down armagetron lol
It would! But it happens after a fork() and only in one of the branches, so it's getting rid of the running copy you don't want any more.
Galaxip wrote: Wed May 27, 2020 10:31 pmi just have a basic understanding of c++ and get lost in the really deep stuff
Don't worry, those bits are essentially C. They're system calls, they have to be.
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

I saw the notification that you had posted and thought maybe you had fixed it :D oh well

i'll have ago
Image Image Image Image
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

I made my first test with fork() to understand whats its all about

in my test the parent kills itsself while the child counts 0 - 9 before exiting
everything worked ok

in armagetron I have to kill the child process, this was just to see what happens as ive not used fork before

now to put it all together

back soon

Code: Select all

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
        pid_t pid = fork();

        if (pid > 0)
        {
                // this is the parent program
                printf("parent exiting\n");
                exit (EXIT_SUCCESS);
        }
        else if (pid == 0)
        {
                // this is the child program
                //int i = 0;
                for (int i=0; i<=9; ++i)
                {
                        printf("%d\n", i);
                        sleep(1);
                }
        }
        else
        {
                // fork failed
                printf("something went wrong with fork()\n");
                return 1;
        }

        printf("end.\n");

        return 0;
}
Image Image Image Image
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

well i've tried some experiments with the server but the results were pretty bad from crashing the server to losing the pipes to not running any scripts at all :P

I'll keep on and see if I can make this work
Image Image Image Image
User avatar
Z-Man
God & Project Admin
Posts: 11585
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Z-Man »

No worries. I suppose fixing this requires one of two things:
1. Deep understanding how fork, exec.., C++ in general interact, plus probably internal Armagetronad knowledge
2. The willingness to just throw flags that sound like they might do the right thing at system functions
I'm halfway between the two :)
I thought it might be a good learning experience for you, but of course it's no use if you just get frustrated trying to grok everything in camp 1. Should I take it over?
User avatar
Galaxip
Core Dumper
Posts: 120
Joined: Wed Aug 24, 2016 10:49 pm
Contact:

Re: sn_SetNetState: Unable to open accept socket on desired port xxxx, Trying next ports...

Post by Galaxip »

Z-Man wrote: No worries. I suppose fixing this requires one of two things:
1. Deep understanding how fork, exec.., C++ in general interact, plus probably internal Armagetronad knowledge
fork is a forkin nightmare but I would get there with time, armagetron does blow my mind its so complex
2. The willingness to just throw flags that sound like they might do the right thing at system functions
I'm halfway between the two :)
I thought it might be a good learning experience for you, but of course it's no use if you just get frustrated trying to grok everything in camp 1.
I think what I need is to set a flag so that when the copy of armagetron closes it tests for the flag and dosnt close the ports ? and the consolelog ?? and the other files ??? im unsure
Should I take it over?
that would be great :D
Image Image Image Image
Post Reply