Guida [NO-IP] [NO HAMACHI] Configurare host per accogliere connessioni esterne al proprio server Metin2

Marco - Cacao ♠

Utente Electrum
20 Settembre 2010
283
10
113
141
Ultima modifica:
La guida di oggi aiuterà spero molti di voi a utilizzare i files 40k su una rete di casa, senza dover usare hamachi o buttare soldi in servizi esterni. E’ necessario però avere una connessione fissa a casa, non ho provato con l’hotspot del telefonino (sicuramente si può anche li ma non garantisco non avendo provato). Serve inoltre avere i sorgenti dei propri eseguibili (game, db, client), non averli non è mai una buona idea. Sfrutteremo inoltre il servizio NO-IP, perchè do per scontato che non abbiate un indirizzo IP esterno statico.

Il tutto è stato eseguito con successo con Freebsd 9.2 ma posso dire che quasi sicuramente non ci saranno problemi anche con le versioni successive, eccezion fatta per la ricerca che dovrete fare dei diversi comandi e tasti di impostazione.

CONFIGURAZIONE SCHEDA DI RETE
Aprite le configurazioni della macchina, prima ancora di avviarla, e andate nelle impostazioni di rete:
36128


Io ho selezionata la chiavetta usb esterna che vedete come prima scelta, ad altri non c’è, e trovano solo la seconda, o ne hanno altre: dovete selezionare la scheda di rete che usate per connettervi ad internet (penso che la Family Controller vada bene se siete connessi con cavo ethernet ma è solo una supposizione che sto facendo, potrebbe essere una cazzata, provate e fatemi sapere, aggiorno la guida in caso).

Ok, ora potete accendere la macchina virtuale.

Recatevi alla macchina virtuale avviata e digitate “sysinstall” (o bsdinstall per 10.3 e successive) per impostare le configurazioni di rete: Configure → Networking → Interfaces → em0 (no ipv6 e DHCP)

Le impostazioni che utilizzo io sono queste. Concentratevi sui seguenti campi:
36129

  • Gateway: qui si mette appunto il gateway della vostra connessione di casa, ovviamente dell’indirizzo locale, dato che avrete quasi certamente una rete nattata;
  • Name Server: qui si mette un DNS funzionante (io ho preso in prestito quello di google);
  • IPv4 address: qui si mette l’indirizzo che sarà SOLO della macchina e dovrà essere SEMPRE quello! Quindi bisogna che questo indirizzo non abbia l’ultima tripletta di numeri troppo piccola (192.168.1.2) perché rischiate che a PC spento questo IP venga assegnato ad un altro dispositivo, causando piccoli fastidi di conflitti IP, e dovrete successivamente recarvi alla pagina di impostazioni del router, digitando il gateway su un qualsiasi browser (http://192.168.1.1), in modo da poter mettere in atto il portforwarding su questo ip.
Io ho fatto una cosa del genere:
36130


Commentiamo: i più attenti noteranno che prima ho messo l’IP che terminava in 17, mentre qui termina in 253. Il motivo è semplicemente che nelle configurazioni di VBOX (virtualbox) ho reinserito a mano l’IP e mi sono scordato quale fosse, era 253. Poi niente avete le porte del mio piccolo privatino da test bucatemi tutto. No scherzo, guardate come ho impostato io e quali porte ho aperto, più o meno c’è da fare così (non ho testato bene quali porte siano effettivamente necessarie, ad esempio le p2p le aprivo prima con una modifica in hamachi, e le ho tenute perché mi andava, ma potete tranquillamente provare ad aprire solo le normali e vedere se funziona, e in caso comunicatelo, o chi si intende bene di reti magari può dire come andrebbe fatto e motivare, in tal caso aggiorno la guida).

Ok, a questo punto la configurazione della rete è pronta, uscite dalle configurazioni con OK → Cancel → Cancel → Exit install.

Rendete quindi le impostazioni effettive, io utilizzo un comando storico:

service netif restart (grazie Arves100)

/etc/rc.d/netif restart

Ma potete tranquillamente fare un reboot credo (anche qui correggetemi se sbaglio).


MODIFICHE DEL CODICE NEI SORGENTI
A questo punto le impostazioni di rete sono a posto, ora c’è da fare qualche modifica nel sorgente game (se non avete i sorgenti del vostro game, db e client buttate quello che avete e procuratevi eseguibili con sorgenti, non siate masochisti), da qui in poi ringrazio @Ikarus_ e @iltizio che hanno sviluppato il codice che vi rilascerò ora.

Recatevi in /common/service.h (o qualunque altro header utilizziate per i defines, gli interruttori per poter attivare o disattivare codice, non implementate mai codice, soprattutto consistente senza interruttori), e aggiungete in un punto qualunque:

Codice:
#define FIX_LOGIN


Recatevi in /game/src/config.cpp e aggiungete sotto alla definizione di g_szInternalIP

char g_szInternalIP[16] = "0";

Questo:

Codice:
#ifdef FIX_LOGIN
char   g_szExternPublicIP[16] = "0";
#endif

Quindi cercate la funzione bool GetIPInfo() e verificate di avere un codice quanto più simile a questo (ora commentiamo i singoli pezzettini):

Codice:
if (!strncmp(netip, "192.168", 7))
             {
                    strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
#ifndef __WIN32__
                    fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
                    fprintf(stderr, "INTERNAL_IP: %s\n", netip);
                    sys_log(0, "INTERNAL_IP: %s\n", g_szInternalIP);
#endif
             }

Il primo pezzettino di codice dice che se la negazione di strncmp (che compara alcuni caratteri di due stringhe) è vera (quindi il valore deve essere 0, e strncmp ritorna 0 quando le due stringhe sono uguali), allora si procede. Operativamente questo significa: se l’ip che mi dai inizia con 192.168 allora io eseguo il codice dopo, quindi è FONDAMENTALE che il vostro IP (locale) inizi con 192.168 e che questo check non sia stato modificato con cose tipo 999.999, altrimenti non loggherete, perché ora lui sta impostando l’ip interno, grazie alla string line copy o come si chiama (strlcpy), che copia netip in g_szInternalIP.

Codice:
else if (!strncmp(netip, "10.", 3))
             {
                    strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
#ifndef __WIN32__
                    fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
                    fprintf(stderr, "INTERNAL_IP: %s\n", netip);
                    sys_log(0, "INTERNAL_IP2: %s\n", g_szInternalIP);
#endif
             }

Questo secondo pezzettino è alternativo al primo, nel senso che se avete l’ip locale che inizia con 10. va bene uguale, e avrete anche in questo caso un ip interno settato correttamente,

Codice:
if (g_szPublicIP[0] == '0')
             {
                    strlcpy(g_szPublicIP, netip, sizeof(g_szPublicIP));
#ifndef __WIN32__
                    fprintf(stderr, "PUBLIC_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
                    fprintf(stderr, "PUBLIC_IP: %s\n", netip);
                    sys_log(0, "PUBLIC_IP: %s\n", g_szPublicIP);
#endif
             }

Questo terzo pezzo invece setta in teoria l’IP esterno, ma come noterete viene copiato sempre netip, quindi avrete in realtà sempre lo stesso IP salvato come “esterno” ed interno. Perché fare così? Boh, funziona ahahah. Questo va oltre le mie conoscenze, quindi se qualcuno vuole dare una spiegazione perché lo sa, o vuole correggere perché è un modo sbagliato di procedere DOVETE farlo, e miglioro la guida. Io l’ho pubblicata così solo perché funziona.
Grazie di nuovo ad @Ikarus_ la risposta è la seguente, sotto spoiler perchè è un approfondimento teorico non obbligatorio per il corretto svolgimento della guida ma sicuramente interessante (c'è sotto ma la integro nella guida in modo che sia tutto insieme, e tra l'altro potevo arrivarci):

"Se hai notato prima di copiare in public ip l'ip della scheda di rete checka se l'ip pubblico è una stringa vuota (se il terminatore nullo è al primo posto nell'array) Questo perchè "g_szPublicIP" è in realtà destinato a essere usato per salvarci l'ip inserito nel file config del core in booting. Questo vuol dire che se tu non hai messo bind_ip nel config, allora viene copiato l'ip preso dalla scheda di rete (che non è quello "interno", lo è solo nel caso di una NAT), che nei dedicati e/o nei vps con ip dedicato è l'ip pubblico. E' un pò come dire, non mi hai assegnato un ip pubblico quindi presumo che possa prenderlo dalla scheda di rete. Se invece hai messo il bind_ip nel config , g_szPublicIP conterrà quell'ip."

In una rete nattata il "g_szPublicIP" non può contenere l'IP esterno (provato tempo fa), mentre nel caso del dedicato, con IP esterno statico (si collega alla rete direttamente con l'indirizzo esterno), ecco che questa variabile assume una serie di caratteri diversi da "g_szInternalIP". È comunque importante che venga assegnato un indirizzo a "g_szPublicIP" quindi assicuratevi che in un modo o nell'altro ciò venga fatto (mi pare desse problemi di login se stringa nulla).]

Bene ora manca il pezzo più importante. Dopo aver controllato questi pezzi di codice, rimanete nella funzione GetIPInfo() e aggiungete appena sotto questi codici appena controllati:

############### EDIT!! ###############
Più in fondo nelle risposte, un post di @Arves100 suggerisce un modo migliore per la prossima modifica che sta per essere proposta, suggerisco caldamente di visionare tale risposta, che non è stata integrata nella guida, sostituendo il codice da me proposto perchè:
  • Non sono ancora riuscito a compilare con successo sulla macchina con gcc8 (c++ 11 se non 14) e freebsd 11.3
  • Tengo conto che probabilmente molta gente che seguirà la guida non avrà aggiornato gcc o freebsd e il codice proposto da Arves richiede l'aggiornamento del compilatore
  • Al momento non sono in grado di integrarlo
Non appena mi sarà possibile integrerò la modifica da lui proposta alla guida, aggiungendo eventualmente un bivio per chi vuole tenersi i files non aggiornati e chi invece vuole tutto a nuovo.
############### FINE ###############

Codice:
#ifdef FIX_LOGIN
             FILE *fp;
             fp = popen("/usr/local/bin/curl ipinfo.io/ip", "r");
             fgets(g_szExternPublicIP, sizeof(g_szExternPublicIP), fp);
             pclose(fp);
             sys_log(0, "EXTERN_NAT_IP : %s for nat fix. \n", g_szExternPublicIP);
#endif

Questo è il codice gentilmente preso in prestito da Ikarus e IlTizio da una discussione di aiuto sempre qui su IF, e tutto quello che fa è prelevare ad ogni avvio del server il vostro IP esterno, e salvarlo in una variabile definita g_szExternPublicIP (che dobbiamo ancora dichiarare ed utilizzare e lo faremo). Qual è la cosa fantastica di questa cosa? Beh semplicemente che se avete una rete nattata, con una frequenza più o meno alta il vostro IP esterno o reale cambierà, e quindi dovreste sempre risettarlo a mano, dal sorgente o dai CONFIG se avete configurato la possibilità di farlo, ma in ogni caso resta un processo manuale. Qui invece avremo la possibilità di far leggere in autonomia alla macchina il vostro IP esterno da un sito, e tutto ciò che dovrete fare per poterlo avere funzionante è installare “curl” sulla vostra macchina, qualora non fosse già presente.

Per installare curl ci sono 60053 modi, io ho usato “pkg install curl” ma cercando su internet se ne trovano a valanghe. Continuiamo con la guida.

Recatevi in config.h e aggiungete sotto a:

extern char g_szInternalIP[16];

questo:

Codice:
#ifdef FIX_LOGIN
extern char  g_szExternPublicIP[16];
#endif

Recatevi in desc_client.cpp, nel metodo bool CLIENT_DESC::Connect(int iPhaseWhenSucceed)

E sostituite:

m_sock = socket_connect(m_stHost.c_str(), m_wPort);

Con:

Codice:
#ifdef FIX_LOGIN
       if (iPhaseWhenSucceed == PHASE_P2P)
       {
             sys_log(0, "Ikarus : IP to connect: %s , Port: %d\n", g_szInternalIP, m_wPort);
             m_sock = socket_connect(g_szInternalIP, m_wPort);
       }
       else
       {
             m_sock = socket_connect(m_stHost.c_str(), m_wPort);
       }
#else
       m_sock = socket_connect(m_stHost.c_str(), m_wPort);
#endif

Se ho interpretato bene questo codice, l’intenzione era quella di passare l’ip interno per le connessioni P2P che non usano ovviamente quello esterno.

Recatevi quindi un po’ più in basso e sostituite:

memcpy(p.szIP, g_szPublicIP, 16);

con:

Codice:
#ifdef FIX_LOGIN
                                        memcpy(p.szIP, g_szExternPublicIP, 16);
#else
                                        memcpy(p.szIP, g_szPublicIP, 16);
#endif

E ancora un po’ più in basso sostituite:

strlcpy(p.szPublicIP, g_szPublicIP, sizeof(p.szPublicIP));

con:

Codice:
#ifdef FIX_LOGIN
                           strlcpy(p.szPublicIP, g_szExternPublicIP, sizeof(p.szPublicIP));
#else
                           strlcpy(p.szPublicIP, g_szPublicIP, sizeof(p.szPublicIP));
#endif

Avete finito anche qua, ricompilate e montate il nuovo game. All’avvio del server, messaggi di questo tipo (ovviamente insieme al fatto che il server è online e logghiate), indicano che la procedura è stata eseguita correttamente:
36131


Se questo messaggio non viene visualizzato sulla console perchè non vedete tipicamente nessun messaggio all'avvio, provate a controllare il file "autorun.log" che trovate nei vari core (dopo l'avvio del server). Se non trovate questo file ma loggate e funziona tutto non è un problema.

Ultimo ma non per importanza, scaricate DUC e impostatevi un NO-IP gratuito perché sebbene la macchina sia capace indipendentemente di ricavarsi l’IP esterno ogni volta, il client non lo è, e quindi per non dovere ogni volta modificare la root vi conviene averlo. Come andremo quindi ad impostare le varie connessioni?

Facciamo un esempio: Ho la mia bellissima vodafone station, a cui sono collegati:
  • Un PC fisso, che ospita la macchina virtuale e chiamaremo A;
  • Un portatile, che chiameremo B.
Poi c’è un altro PC sfigato che si trova in Burundi e quindi non è collegato alla station e lo chiamiamo C.

Se A si vuole collegare al server può entrare sia in locale (127.0.0.1) che con l’ip locale (192.168.1.253 nel mio caso), e questo IP è fisso per la macchina quindi non ci saranno grossi problemi (quindi per il DB metterete l’ip locale e id e pass, idem per il ftp e idem per il root).

Se B si vuole collegare al server può entrare con l’ip interno (anzi DEVE entrare così, non gli sarà possibile entrare con l’IP ESTERNO, quindi per una questione di comodità vi conviene decidere quali pc si collegheranno con IP interno e quali con esterno, non so se mi sono spiegato), quindi mettendo 192.168.1.253.

Se C si vuole collegare dal Burundi, sia a navicat che a winscp che al client non dovrà fare altro che inserire l’indirizzo alfanumerico che è stato registrato su no-ip, quindi che ne so: testmetin2.ddns.net, quando DUC sarà avviato sul pc HOST potrà collegarsi senza problemi.

Ribadisco che pc collegati alla station su cui si poggia la macchina virtuale DEVONO entrare con l’IP interno, o almeno i test mi portano a dire questo. Testate e ditemi come va, in caso di problemi scrivete sotto e aggiorno la guida. Se ci sono altre guide migliori mi scuso e cancello, se avete critiche soprattutto inutili fatele, altrimenti ci annoiamo. Potrei essermi scordato qualche passaggio perché ho partorito questa idea in più tempi, e quindi alcune modifiche le ho fatte recentemente, altre secoli addietro.

Tengo a precisare che la guida deriva da varie unioni di richieste di aiuto su questo forum e quindi i singoli passaggi potrebbero essere reperibili nelle varie richieste, oltre a guide proprio che però secondo me non coprono l'argomento in maniera esaustiva in quanto, ad oggi, esistono ancora richieste per loggare correttamente sul proprio server e far loggare amici.

Buona giornata a tutti.
 
Piccola nota qui:
#ifdef FIX_LOGIN
FILE *fp;
fp = popen("/usr/local/bin/curl ipinfo.io/ip", "r");
fgets(g_szExternPublicIP, sizeof(g_szExternPublicIP), fp);
pclose(fp);
sys_log(0, "EXTERN_NAT_IP : %s for nat fix. \n", g_szExternPublicIP);
#endif

Se avvio senza utilizzare internet, non oso immaginare cosa verrà impostato come IP esterno, questa funzione dovrebbe essere, a mio parere, configurabile nel CONFIG (magari utilizzando un g_enableExternalNat da aggiungere in config.h "extern bool g_enableExternalNat" e su config.cpp "bool g_enableExternalNat = true; e compagnia).

Oltretutto, il seguente codice non funziona su Windows o altri sistemi per la posizione di curl (impostata a /usr/local/bin/curl, oltretutto Windows esporta _popen perchè è MSVC)

Visto che abbiamo la potenza di Boost (in questo caso Boost.Beast), se compiliamo Boost_date_time possiamo utilizzare un piccolo codice per eseguire una richiesta HTTP (verificato, ipinfo.io/ip non obblica il TLS), evitando di hardcoddare la path di Curl.

NOTA: Codice adattato dall'esempio di un client HTTP di Boost.
Testato con Boost 1.70.0 funziona correttamente.
Il codice richiede il C++11, se usi GCC versione 4 aggiorna.

Codice:
// Nuove inclusioni / codice dopo l'ultimo include:
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
namespace http = boost::beast::http;    // from <boost/beast/http.hpp>
// Performs an HTTP GET and prints the response
std::string httpGetBeast(const char* host, const char* port, const char* target)
{
    try
    {
        // The io_context is required for all I/O
        boost::asio::io_context ioc;
        // These objects perform our I/O
        tcp::resolver resolver{ioc};
        tcp::socket socket{ioc};
        // Look up the domain name
        auto const results = resolver.resolve(host, port);
        // Make the connection on the IP address we get from a lookup
        boost::asio::connect(socket, results.begin(), results.end());
        // Set up an HTTP GET request message
        http::request<http::string_body> req{http::verb::get, target, 11};
        req.set(http::field::host, host);
        req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
        // Send the HTTP request to the remote host
        http::write(socket, req);
        // This buffer is used for reading and must be persisted
        boost::beast::flat_buffer buffer;
        // Declare a container to hold the response
        http::response<http::string_body> res;
        // Receive the HTTP response
        http::read(socket, buffer, res);
        std::string str = res.body();
        str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char x){ return x == '\r' || x == '\n';}), str.end());
        // Gracefully close the socket
        boost::system::error_code ec;
        socket.shutdown(tcp::socket::shutdown_both, ec);
        // not_connected happens sometimes
        // so don't bother reporting it.
        //
        if(ec && ec != boost::system::errc::not_connected)
            throw boost::system::system_error{ec};
        return str;
    }
    catch(std::exception const& e)
    {
        sys_log(0, "Error while doing an http request to %s:%s => %s", host, port, e.what());
    }
   
    return "";
}
// Vecchio codice:
#ifdef FIX_LOGIN
             FILE *fp;
             fp = popen("/usr/local/bin/curl ipinfo.io/ip", "r");
             fgets(g_szExternPublicIP, sizeof(g_szExternPublicIP), fp);
             pclose(fp);
             sys_log(0, "EXTERN_NAT_IP : %s for nat fix. \n", g_szExternPublicIP);
#endif
// Nuovo codice (cross-platform)
#ifdef FIX_LOGIN
#if defined(_MSC_VER) && _MSC_VER > 1500
    strcpy_s(g_szExternPublicIP, _countof(g_szExternPublicIP), httpGetBeast("ipinfo.io", "80", "/ip").c_str());
#else
    strcpy(g_szExternPublicIP, httpGetBeast("ipinfo.io", "80", "/ip").c_str());
#endif

// Piccola nota: qui metto l'IP esterno come IP interlo, sentitevi liberi di cambiare come volete (in caso di mancata connessione ad internet)
if (strlen(g_szExternPublicIP) < 1)
{
#if defined(_MSC_VER) && _MSC_VER > 1500
    strcpy_s(g_szExternPublicIP, _countof(g_szExternPublicIP),g_szInternalIP);
#else
    strcpy(g_szExternPublicIP,g_szInternalIP);
#endif
}
#endif

/etc/rc.d/netif restart è molto FreeBSD 7, su FreeBSD nuovi puoi usare semplicemente service netif restart.
Non è richiesto il reboot perchè riavviamo già la rete con netif.

Il resto mi sembra tutto ok. Saluti.
 
Ottima guida, potresti indetarla meglio per rendere più semplice la lettura, ad esempio racchiudendo i codici nello script "Codice".
 
  • Mi piace
Reazioni: IlSolista
Ultima modifica:
io ho usato sempre il comando ping per testare connessione a internet (nella mia ignoranza) e dopo queste modifiche riuscivo a pingare google. Sulla mia station di casa il firewall è disattivato (masochismo) quindi col firewall acceso, ammesso che tu lo abbia, potrebbero esserci delle cose da sistemare che non ho avuto modo di conoscere (e che testerò domani).

Ti chiedo di informarmi circa la tua situazione, mi interessa:
-Entri su winscp, navicat e in game col client dal pc HOST?? -> Corretto settaggio scheda di rete macchina virtuale e modifiche ai sorgenti (per il login)
-Entri su winscp, navicat e in game col client da un pc da un'altra rete? -> corretto portforwarding del router e settaggio eventuali firewall che in questo momento esulano dalla guida (oltre ai corretti settaggi del punto prima che sono inclusi in questo secondo punto).
-All'avvio del server si vedono le stampe a schermo su console riportate nella 4°a immagine? (quella che indica IP interni e quello "esterno" uguale all'interno e i tempi di risposta del curl) -> prova del 9

Rivedi attentamente la guida, se tutto è stato modificato ad hoc, tenta di disattivare per un brevissimo momento il firewall e tenta la connessione, in caso il problema persistesse, o se non ti andasse di farlo, attendi che qualcun'altro o io domani testiamo altri casi evidentemente da me non previsti.

Fornisci tutte le informazioni circa il tuo problema, ogni dettaglio tralasciato potrebbe aiutare a non risolvere :p
 
  • Mi piace
Reazioni: hunterxdd
io ho usato sempre il comando ping per testare connessione a internet (nella mia ignoranza) e dopo queste modifiche riuscivo a pingare google. Sulla mia station di casa il firewall è disattivato (masochismo) quindi col firewall acceso, ammesso che tu lo abbia, potrebbero esserci delle cose da sistemare che non ho avuto modo di conoscere (e che testerò domani).

Ti chiedo di informarmi circa la tua situazione, mi interessa:
-Entri su winscp, navicat e in game col client dal pc HOST?? -> Corretto settaggio scheda di rete macchina virtuale e modifiche ai sorgenti (per il login)
-Entri su winscp, navicat e in game col client da un pc da un'altra rete? -> corretto portforwarding del router e settaggio eventuali firewall che in questo momento esulano dalla guida (oltre ai corretti settaggi del punto prima che sono inclusi in questo secondo punto).
-All'avvio del server si vedono le stampe a schermo su console riportate nella 4°a immagine? (quella che indica IP interni e quello "esterno" uguale all'interno e i tempi di risposta del curl) -> prova del 9

Rivedi attentamente la guida, se tutto è stato modificato ad hoc, tenta di disattivare per un brevissimo momento il firewall e tenta la connessione, in caso il problema persistesse, o se non ti andasse di farlo, attendi che qualcun'altro o io domani testiamo altri casi evidentemente da me non previsti.

Fornisci tutte le informazioni circa il tuo problema, ogni dettaglio tralasciato potrebbe aiutare a non risolvere :p


Ciao Marco,

Ho risolto cambiando la porta MARK essendo tale bloccata dal ddns che sto utilizzando. "non ho ancora capito perchè".
Per quanto riguarda il mio server raggiungo dalla rete locale ssh & navicat. "non espongo su internet il db e la VM, così da ridurre al minimo la possibilità di attacchi hacker".
per quanto riguarda la schermata "4°a immagine" a me non mostra nulla all'avvio però funziona tutto correttamente quindi mi accontento così :).


Se hai bisogno di altre info non esitare a chiedere.
 
  • Mi piace
Reazioni: Marco - Cacao ♠
Ultima modifica:
quindi avrete in realtà sempre lo stesso IP salvato come “esterno” ed interno. Perché fare così? Boh, funziona ahahah
Se hai notato prima di copiare in public ip l'ip della scheda di rete checka se l'ip pubblico è una stringa vuota (se il terminatore nullo è al primo posto nell'array)
Questo perchè "g_szPublicIP" è in realtà destinato a essere usato per salvarci l'ip inserito nel file config del core in booting.
Questo vuol dire che se tu non hai messo bind_ip nel config, allora viene copiato l'ip preso dalla scheda di rete (che non è quello "interno", lo è solo nel caso di una NAT), che nei dedicati e/o nei vps con ip dedicato è l'ip pubblico. E' un pò come dire, non mi hai assegnato un ip pubblico quindi presumo che possa prenderlo dalla scheda di rete. Se invece hai messo il bind_ip nel config , g_szPublicIP conterrà quell'ip.
 
  • Mi piace
Reazioni: Marco - Cacao ♠
Giorno ragazzi, ho cercato di seguire questa guida nella maniera più fedele possibile ma nel momento in cui avvio il server ho questo errore:
Visualizza allegato 36888
Mentre per quanto riguarda il Sysser del channel 1 ad esempio ho questa serie di errori:
Visualizza allegato 36889

Qualcuno ci è già passato? non ho la benchè minima idea di come risolvere questo problema, accetto qualsiasi consiglio o dritta.
Grazie in anticipo, saluti.
Probabilmente la tua server machine non ha accesso a internet, e per questo motivo non rileva l'IP tramite curl.
Per sapere se ho ragione basta provare a pingare google.
Codice:
ping -c 10 8.8.8.8
Se ti da 100% packets lost vuol dire che non hai internet sulla macchina
 
  • Mi piace
Reazioni: MrPervertito
Il tuo g_szInternalIP è nullo (lo dice nell'errore che hai postato, è impostato su 0) devi verificare cosa è successo in config.cpp nei pressi dei punto modificati nella guida, probabilmente hai toccato qualcosa che non dovevi, nel senso che forse hai tolto un pezzo di codice pensando dovessi sostituire.
Se hai backuppato prima di seguire la guida ti consiglio di ripartire dal backup e rifare i passaggi stando più attento, altrimenti puoi postare il tuo config.cpp e desc_client.cpp sotto tag codice e spoiler cosi da farmi dare un occhiata (meglio ancora se usi pastebin)
 
  • Mi piace
Reazioni: MrPervertito
C++:
//search:

        if (g_szPublicIP[0] == '0')
        {
            strlcpy(g_szPublicIP, netip, sizeof(g_szPublicIP));
            fprintf(stderr, "PUBLIC_IP: %s interface %s\n", netip, ifap->ifa_name);
        }

//new line and add:
        strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
 
  • Mi piace
Reazioni: MrPervertito
Ciao pervertito (suona male detta cosi), come suggerito da Ikarus ti invito a ripulire tutte le modifiche e quindi inserire nuovamente il codice e ripetere i passaggi con più calma. Se non risolvi il problema mi rendo disponibile ad aiutarti via skype, in modo che io possa capire quali punti ti sono risultati meno chiari, e quindi sistemare la guida, correggendo incomprensioni, o peggio errori. Riprova prima seguendo la guida, e solo se non risolvessi, puoi contattarmi in privato, mandandomi il tuo skype per poter vedere insieme (nel thread di aiuto ho visto cose brutte, quindi soffermati bene su ogni passaggio).
 
  • Mi piace
Reazioni: MrPervertito
Beh direi che quel "Non appena potrò ricominciare a lavorare, sicuramente la utilizzerò. " si è avverato.

Testata, funzionante e bellissima la mia vps locale :figurati:
 
  • Mi piace
Reazioni: Marco - Cacao ♠
La guida funziona correttamente, probabilmente qualche passaggio lo hai sbagliato oppure saltato completamente.
Postaci magari il tuo SYS e ti consiglio di ricontrollare la procedura dell'apertura delle Porte sul tuo router.
Messaggio unito automaticamente:

Buonasera a tutti
ho seguito la guida ma alla scelta del personaggio ritorno alla schermata del login
come posso risolvere??
 
  • Mi piace
Reazioni: MyNameIsBack
Mi sa che le aperture sul router sono il problema
Ho Telecom con tim hub aprendo le porte mi risultano comunque chiuse
Qualcuno con Telecom che può aiutarmi??
Chiamando anche l’assistenza mi chiedono 30 euro per sbloccare le porte ..

Non so di preciso la versione del Router, in ogni caso TIM HUB permette di sbloccare le porte in maniera anche abbastanza semplice.

Clic
 
  • Mi piace
Reazioni: MyNameIsBack
Le ho aperte tutte ma mi risultato comunque chiuse
Non è un problema solo mio ma in giro con Tim tutti si trovano questo problema
Se magari non so se può aiutarmi anche sentendoci su Skype o Discord come preferisce
Va bene aggiungimi su Discord Mefisto#4915


-> Nel caso trovassimo una soluzione a questo problema, la condivideremo sotto questo Thread in modo che tutti possano usufruirne.
 
  • Mi piace
Reazioni: MyNameIsBack
Il tizio aveva dimenticato di seguire alcuni semplici passaggi:

Assegnazione di un IP statico alla VM (consigliabile)
DUC non impostato

LE PORTE DEL ROUTER ERANO APERTE CORRETTAMENTE, E NON NECESSITA DI PAGAMENTI DI NESSUN GENERE PER POTERLE APRIRE.
 
  • Mi piace
Reazioni: MyNameIsBack
Ottima guida, potresti indetarla meglio per rendere più semplice la lettura, ad esempio racchiudendo i codici nello script "Codice".

Ammetto che nel rileggerla dopo il tuo commento mi stava sanguinando il sangue che sanguinava dagli occhi. Solo che oggi ero di fretta e l'ho incollata dal file di word. Spero ora sia più bella da leggere.
 
Ciao Marco, Bellissima guida ha funzionato però adesso ho un altro problema:

USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
root game 2939 13 tcp4 192.168.1.200:13099 *:*
root game 2939 14 tcp4 192.168.1.200:14099 *:*
root game 2934 13 tcp4 192.168.1.200:13000 *:*
root game 2934 14 tcp4 192.168.1.200:14000 *:*
root game 2929 13 tcp4 192.168.1.200:13002 *:*
root game 2929 14 tcp4 192.168.1.200:14002 *:*
root game 2923 13 tcp4 192.168.1.200:13001 *:*
root game 2923 14 tcp4 192.168.1.200:14001 *:*
root game 2919 12 tcp4 192.168.1.200:11000 *:*
root game 2919 13 tcp4 192.168.1.200:12000 *:*
root db 2904 19 tcp4 127.0.0.1:15000 *:*


root@mxxxx:/usr/game/core/ch1/game1 # telnet mxxxx.dns.org 13001
Trying 2.123.90.206...
telnet: connect to address 2.123.90.206: Connection refused
telnet: Unable to connect to remote host

la 13001 è la porta MARK. è correttamente aperta lato router.

Lato server perchè viene bloccata?
 
Ciao Marco,

Ho risolto cambiando la porta MARK essendo tale bloccata dal ddns che sto utilizzando. "non ho ancora capito perchè".
Per quanto riguarda il mio server raggiungo dalla rete locale ssh & navicat. "non espongo su internet il db e la VM, così da ridurre al minimo la possibilità di attacchi hacker".
per quanto riguarda la schermata "4°a immagine" a me non mostra nulla all'avvio però funziona tutto correttamente quindi mi accontento così :).


Se hai bisogno di altre info non esitare a chiedere.

Da qualche parte dovrebbe stamparli in quanto fa parte del codice (prova a vedere in autorun.log nei vari core), avrai disabilitato la stampa a schermo durante l'avvio dei vari messaggi (integro nella guida).

EDIT: vedevo ora stampa anche nei syslog.

In ogni caso se logghi tu ed i tuoi amici siamo a posto!
 
La guida di oggi aiuterà spero molti di voi a utilizzare i files 40k su una rete di casa, senza dover usare hamachi o buttare soldi in servizi esterni. E’ necessario però avere una connessione fissa a casa, non ho provato con l’hotspot del telefonino (sicuramente si può anche li ma non garantisco non avendo provato). Serve inoltre avere i sorgenti dei propri eseguibili (game, db, client), non averli non è mai una buona idea. Sfrutteremo inoltre il servizio NO-IP, perchè do per scontato che non abbiate un indirizzo IP esterno statico.

Il tutto è stato eseguito con successo con Freebsd 9.2 ma posso dire che quasi sicuramente non ci saranno problemi anche con le versioni successive, eccezion fatta per la ricerca che dovrete fare dei diversi comandi e tasti di impostazione.

CONFIGURAZIONE SCHEDA DI RETE
Aprite le configurazioni della macchina, prima ancora di avviarla, e andate nelle impostazioni di rete:
Visualizza allegato 36128

Io ho selezionata la chiavetta usb esterna che vedete come prima scelta, ad altri non c’è, e trovano solo la seconda, o ne hanno altre: dovete selezionare la scheda di rete che usate per connettervi ad internet (penso che la Family Controller vada bene se siete connessi con cavo ethernet ma è solo una supposizione che sto facendo, potrebbe essere una cazzata, provate e fatemi sapere, aggiorno la guida in caso).

Ok, ora potete accendere la macchina virtuale.

Recatevi alla macchina virtuale avviata e digitate “sysinstall” (o bsdinstall per 10.3 e successive) per impostare le configurazioni di rete: Configure → Networking → Interfaces → em0 (no ipv6 e DHCP)

Le impostazioni che utilizzo io sono queste. Concentratevi sui seguenti campi:
Visualizza allegato 36129
  • Gateway: qui si mette appunto il gateway della vostra connessione di casa, ovviamente dell’indirizzo locale, dato che avrete quasi certamente una rete nattata;
  • Name Server: qui si mette un DNS funzionante (io ho preso in prestito quello di google);
  • IPv4 address: qui si mette l’indirizzo che sarà SOLO della macchina e dovrà essere SEMPRE quello! Quindi bisogna che questo indirizzo non abbia l’ultima tripletta di numeri troppo piccola (192.168.1.2) perché rischiate che a PC spento questo IP venga assegnato ad un altro dispositivo, causando piccoli fastidi di conflitti IP, e dovrete successivamente recarvi alla pagina di impostazioni del router, digitando il gateway su un qualsiasi browser (http://192.168.1.1), in modo da poter mettere in atto il portforwarding su questo ip.
Io ho fatto una cosa del genere:
Visualizza allegato 36130

Commentiamo: i più attenti noteranno che prima ho messo l’IP che terminava in 17, mentre qui termina in 253. Il motivo è semplicemente che nelle configurazioni di VBOX (virtualbox) ho reinserito a mano l’IP e mi sono scordato quale fosse, era 253. Poi niente avete le porte del mio piccolo privatino da test bucatemi tutto. No scherzo, guardate come ho impostato io e quali porte ho aperto, più o meno c’è da fare così (non ho testato bene quali porte siano effettivamente necessarie, ad esempio le p2p le aprivo prima con una modifica in hamachi, e le ho tenute perché mi andava, ma potete tranquillamente provare ad aprire solo le normali e vedere se funziona, e in caso comunicatelo, o chi si intende bene di reti magari può dire come andrebbe fatto e motivare, in tal caso aggiorno la guida).

Ok, a questo punto la configurazione della rete è pronta, uscite dalle configurazioni con OK → Cancel → Cancel → Exit install.

Rendete quindi le impostazioni effettive, io utilizzo un comando storico:

/etc/rc.d/netif restart

Ma potete tranquillamente fare un reboot credo (anche qui correggetemi se sbaglio).

MODIFICHE DEL CODICE NEI SORGENTI
A questo punto le impostazioni di rete sono a posto, ora c’è da fare qualche modifica nel sorgente game (se non avete i sorgenti del vostro game, db e client buttate quello che avete e procuratevi eseguibili con sorgenti, non siate masochisti), da qui in poi ringrazio @Ikarus_ e @iltizio che hanno sviluppato il codice che vi rilascerò ora.

Recatevi in /common/service.h (o qualunque altro header utilizziate per i defines, gli interruttori per poter attivare o disattivare codice, non implementate mai codice, soprattutto consistente senza interruttori), e aggiungete in un punto qualunque:

Codice:
#define FIX_LOGIN


Recatevi in /game/src/config.cpp e aggiungete sotto alla definizione di g_szInternalIP

char g_szInternalIP[16] = "0";

Questo:

Codice:
#ifdef FIX_LOGIN
char   g_szExternPublicIP[16] = "0";
#endif

Quindi cercate la funzione bool GetIPInfo() e verificate di avere un codice quanto più simile a questo (ora commentiamo i singoli pezzettini):

Codice:
if (!strncmp(netip, "192.168", 7))
             {
                    strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
#ifndef __WIN32__
                    fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
                    fprintf(stderr, "INTERNAL_IP: %s\n", netip);
                    sys_log(0, "INTERNAL_IP: %s\n", g_szInternalIP);
#endif
             }

Il primo pezzettino di codice dice che se la negazione di strncmp (che compara alcuni caratteri di due stringhe) è vera (quindi il valore deve essere 0, e strncmp ritorna 0 quando le due stringhe sono uguali), allora si procede. Operativamente questo significa: se l’ip che mi dai inizia con 192.168 allora io eseguo il codice dopo, quindi è FONDAMENTALE che il vostro IP (locale) inizi con 192.168 e che questo check non sia stato modificato con cose tipo 999.999, altrimenti non loggherete, perché ora lui sta impostando l’ip interno, grazie alla string line copy o come si chiama (strlcpy), che copia netip in g_szInternalIP.

Codice:
else if (!strncmp(netip, "10.", 3))
             {
                    strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
#ifndef __WIN32__
                    fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
                    fprintf(stderr, "INTERNAL_IP: %s\n", netip);
                    sys_log(0, "INTERNAL_IP2: %s\n", g_szInternalIP);
#endif
             }

Questo secondo pezzettino è alternativo al primo, nel senso che se avete l’ip locale che inizia con 10. va bene uguale, e avrete anche in questo caso un ip interno settato correttamente,

Codice:
if (g_szPublicIP[0] == '0')
             {
                    strlcpy(g_szPublicIP, netip, sizeof(g_szPublicIP));
#ifndef __WIN32__
                    fprintf(stderr, "PUBLIC_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
                    fprintf(stderr, "PUBLIC_IP: %s\n", netip);
                    sys_log(0, "PUBLIC_IP: %s\n", g_szPublicIP);
#endif
             }

Questo terzo pezzo invece setta in teoria l’IP esterno, ma come noterete viene copiato sempre netip, quindi avrete in realtà sempre lo stesso IP salvato come “esterno” ed interno. Perché fare così? Boh, funziona ahahah. Questo va oltre le mie conoscenze, quindi se qualcuno vuole dare una spiegazione perché lo sa, o vuole correggere perché è un modo sbagliato di procedere DOVETE farlo, e miglioro la guida. Io l’ho pubblicata così solo perché funziona.
Grazie di nuovo ad @Ikarus_ la risposta è la seguente, sotto spoiler perchè è un approfondimento teorico non obbligatorio per il corretto svolgimento della guida ma sicuramente interessante (c'è sotto ma la integro nella guida in modo che sia tutto insieme, e tra l'altro potevo arrivarci):

"Se hai notato prima di copiare in public ip l'ip della scheda di rete checka se l'ip pubblico è una stringa vuota (se il terminatore nullo è al primo posto nell'array) Questo perchè "g_szPublicIP" è in realtà destinato a essere usato per salvarci l'ip inserito nel file config del core in booting. Questo vuol dire che se tu non hai messo bind_ip nel config, allora viene copiato l'ip preso dalla scheda di rete (che non è quello "interno", lo è solo nel caso di una NAT), che nei dedicati e/o nei vps con ip dedicato è l'ip pubblico. E' un pò come dire, non mi hai assegnato un ip pubblico quindi presumo che possa prenderlo dalla scheda di rete. Se invece hai messo il bind_ip nel config , g_szPublicIP conterrà quell'ip."

In una rete nattata il "g_szPublicIP" non può contenere l'IP esterno (provato tempo fa), mentre nel caso del dedicato, con IP esterno statico (si collega alla rete direttamente con l'indirizzo esterno), ecco che questa variabile assume una serie di caratteri diversi da "g_szInternalIP". È comunque importante che venga assegnato un indirizzo a "g_szPublicIP" quindi assicuratevi che in un modo o nell'altro ciò venga fatto (mi pare desse problemi di login se stringa nulla).]

Bene ora manca il pezzo più importante. Dopo aver controllato questi pezzi di codice, rimanete nella funzione GetIPInfo() e aggiungete appena sotto questi codici appena controllati:

Codice:
#ifdef FIX_LOGIN
             FILE *fp;
             fp = popen("/usr/local/bin/curl ipinfo.io/ip", "r");
             fgets(g_szExternPublicIP, sizeof(g_szExternPublicIP), fp);
             pclose(fp);
             sys_log(0, "EXTERN_NAT_IP : %s for nat fix. \n", g_szExternPublicIP);
#endif

Questo è il codice gentilmente preso in prestito da Ikarus e IlTizio da una discussione di aiuto sempre qui su IF, e tutto quello che fa è prelevare ad ogni avvio del server il vostro IP esterno, e salvarlo in una variabile definita g_szExternPublicIP (che dobbiamo ancora dichiarare ed utilizzare e lo faremo). Qual è la cosa fantastica di questa cosa? Beh semplicemente che se avete una rete nattata, con una frequenza più o meno alta il vostro IP esterno o reale cambierà, e quindi dovreste sempre risettarlo a mano, dal sorgente o dai CONFIG se avete configurato la possibilità di farlo, ma in ogni caso resta un processo manuale. Qui invece avremo la possibilità di far leggere in autonomia alla macchina il vostro IP esterno da un sito, e tutto ciò che dovrete fare per poterlo avere funzionante è installare “curl” sulla vostra macchina, qualora non fosse già presente.

Per installare curl ci sono 60053 modi, io ho usato “pkg install curl” ma cercando su internet se ne trovano a valanghe. Continuiamo con la guida.

Recatevi in config.h e aggiungete sotto a:

extern char g_szInternalIP[16];

questo:

Codice:
#ifdef FIX_LOGIN
extern char  g_szExternPublicIP[16];
#endif

Recatevi in desc_client.cpp, nel metodo bool CLIENT_DESC::Connect(int iPhaseWhenSucceed)

E sostituite:

m_sock = socket_connect(m_stHost.c_str(), m_wPort);

Con:

Codice:
#ifdef FIX_LOGIN
       if (iPhaseWhenSucceed == PHASE_P2P)
       {
             sys_log(0, "Ikarus : IP to connect: %s , Port: %d\n", g_szInternalIP, m_wPort);
             m_sock = socket_connect(g_szInternalIP, m_wPort);
       }
       else
       {
             m_sock = socket_connect(m_stHost.c_str(), m_wPort);
       }
#else
       m_sock = socket_connect(m_stHost.c_str(), m_wPort);
#endif

Se ho interpretato bene questo codice, l’intenzione era quella di passare l’ip interno per le connessioni P2P che non usano ovviamente quello esterno.

Recatevi quindi un po’ più in basso e sostituite:

memcpy(p.szIP, g_szPublicIP, 16);

con:

Codice:
#ifdef FIX_LOGIN
                                        memcpy(p.szIP, g_szExternPublicIP, 16);
#else
                                        memcpy(p.szIP, g_szPublicIP, 16);
#endif

E ancora un po’ più in basso sostituite:

strlcpy(p.szPublicIP, g_szPublicIP, sizeof(p.szPublicIP));

con:

Codice:
#ifdef FIX_LOGIN
                           strlcpy(p.szPublicIP, g_szExternPublicIP, sizeof(p.szPublicIP));
#else
                           strlcpy(p.szPublicIP, g_szPublicIP, sizeof(p.szPublicIP));
#endif

Avete finito anche qua, ricompilate e montate il nuovo game. All’avvio del server, messaggi di questo tipo (ovviamente insieme al fatto che il server è online e logghiate), indicano che la procedura è stata eseguita correttamente:
Visualizza allegato 36131

Se questo messaggio non viene visualizzato sulla console perchè non vedete tipicamente nessun messaggio all'avvio, provate a controllare il file "autorun.log" che trovate nei vari core (dopo l'avvio del server). Se non trovate questo file ma loggate e funziona tutto non è un problema.

Ultimo ma non per importanza, scaricate DUC e impostatevi un NO-IP gratuito perché sebbene la macchina sia capace indipendentemente di ricavarsi l’IP esterno ogni volta, il client non lo è, e quindi per non dovere ogni volta modificare la root vi conviene averlo. Come andremo quindi ad impostare le varie connessioni?

Facciamo un esempio: Ho la mia bellissima vodafone station, a cui sono collegati:
  • Un PC fisso, che ospita la macchina virtuale e chiamaremo A;
  • Un portatile, che chiameremo B.
Poi c’è un altro PC sfigato che si trova in Burundi e quindi non è collegato alla station e lo chiamiamo C.

Se A si vuole collegare al server può entrare sia in locale (127.0.0.1) che con l’ip locale (192.168.1.253 nel mio caso), e questo IP è fisso per la macchina quindi non ci saranno grossi problemi (quindi per il DB metterete l’ip locale e id e pass, idem per il ftp e idem per il root).

Se B si vuole collegare al server può entrare con l’ip interno (anzi DEVE entrare così, non gli sarà possibile entrare con l’IP ESTERNO, quindi per una questione di comodità vi conviene decidere quali pc si collegheranno con IP interno e quali con esterno, non so se mi sono spiegato), quindi mettendo 192.168.1.253.

Se C si vuole collegare dal Burundi, sia a navicat che a winscp che al client non dovrà fare altro che inserire l’indirizzo alfanumerico che è stato registrato su no-ip, quindi che ne so: testmetin2.ddns.net, quando DUC sarà avviato sul pc HOST potrà collegarsi senza problemi.

Ribadisco che pc collegati alla station su cui si poggia la macchina virtuale DEVONO entrare con l’IP interno, o almeno i test mi portano a dire questo. Testate e ditemi come va, in caso di problemi scrivete sotto e aggiorno la guida. Se ci sono altre guide migliori mi scuso e cancello, se avete critiche soprattutto inutili fatele, altrimenti ci annoiamo. Potrei essermi scordato qualche passaggio perché ho partorito questa idea in più tempi, e quindi alcune modifiche le ho fatte recentemente, altre secoli addietro.

Tengo a precisare che la guida deriva da varie unioni di richieste di aiuto su questo forum e quindi i singoli passaggi potrebbero essere reperibili nelle varie richieste, oltre a guide proprio che però secondo me non coprono l'argomento in maniera esaustiva in quanto, ad oggi, esistono ancora richieste per loggare correttamente sul proprio server e far loggare amici.

Buona giornata a tutti.
Ci voleva una nuova guida finalmente
 
Piccola nota qui:
#ifdef FIX_LOGIN
FILE *fp;
fp = popen("/usr/local/bin/curl ipinfo.io/ip", "r");
fgets(g_szExternPublicIP, sizeof(g_szExternPublicIP), fp);
pclose(fp);
sys_log(0, "EXTERN_NAT_IP : %s for nat fix. \n", g_szExternPublicIP);
#endif

Se avvio senza utilizzare internet, non oso immaginare cosa verrà impostato come IP esterno, questa funzione dovrebbe essere, a mio parere, configurabile nel CONFIG (magari utilizzando un g_enableExternalNat da aggiungere in config.h "extern bool g_enableExternalNat" e su config.cpp "bool g_enableExternalNat = true; e compagnia).

Oltretutto, il seguente codice non funziona su Windows o altri sistemi per la posizione di curl (impostata a /usr/local/bin/curl, oltretutto Windows esporta _popen perchè è MSVC)

Visto che abbiamo la potenza di Boost (in questo caso Boost.Beast), se compiliamo Boost_date_time possiamo utilizzare un piccolo codice per eseguire una richiesta HTTP (verificato, ipinfo.io/ip non obblica il TLS), evitando di hardcoddare la path di Curl.

NOTA: Codice adattato dall'esempio di un client HTTP di Boost.
Testato con Boost 1.70.0 funziona correttamente.
Il codice richiede il C++11, se usi GCC versione 4 aggiorna.

Codice:
// Nuove inclusioni / codice dopo l'ultimo include:
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
namespace http = boost::beast::http;    // from <boost/beast/http.hpp>
// Performs an HTTP GET and prints the response
std::string httpGetBeast(const char* host, const char* port, const char* target)
{
    try
    {
        // The io_context is required for all I/O
        boost::asio::io_context ioc;
        // These objects perform our I/O
        tcp::resolver resolver{ioc};
        tcp::socket socket{ioc};
        // Look up the domain name
        auto const results = resolver.resolve(host, port);
        // Make the connection on the IP address we get from a lookup
        boost::asio::connect(socket, results.begin(), results.end());
        // Set up an HTTP GET request message
        http::request<http::string_body> req{http::verb::get, target, 11};
        req.set(http::field::host, host);
        req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
        // Send the HTTP request to the remote host
        http::write(socket, req);
        // This buffer is used for reading and must be persisted
        boost::beast::flat_buffer buffer;
        // Declare a container to hold the response
        http::response<http::string_body> res;
        // Receive the HTTP response
        http::read(socket, buffer, res);
        std::string str = res.body();
        str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char x){ return x == '\r' || x == '\n';}), str.end());
        // Gracefully close the socket
        boost::system::error_code ec;
        socket.shutdown(tcp::socket::shutdown_both, ec);
        // not_connected happens sometimes
        // so don't bother reporting it.
        //
        if(ec && ec != boost::system::errc::not_connected)
            throw boost::system::system_error{ec};
        return str;
    }
    catch(std::exception const& e)
    {
        sys_log(0, "Error while doing an http request to %s:%s => %s", host, port, e.what());
    }
  
    return "";
}
// Vecchio codice:
#ifdef FIX_LOGIN
             FILE *fp;
             fp = popen("/usr/local/bin/curl ipinfo.io/ip", "r");
             fgets(g_szExternPublicIP, sizeof(g_szExternPublicIP), fp);
             pclose(fp);
             sys_log(0, "EXTERN_NAT_IP : %s for nat fix. \n", g_szExternPublicIP);
#endif
// Nuovo codice (cross-platform)
#ifdef FIX_LOGIN
#if defined(_MSC_VER) && _MSC_VER > 1500
    strcpy_s(g_szExternPublicIP, _countof(g_szExternPublicIP), httpGetBeast("ipinfo.io", "80", "/ip").c_str());
#else
    strcpy(g_szExternPublicIP, httpGetBeast("ipinfo.io", "80", "/ip").c_str());
#endif

// Piccola nota: qui metto l'IP esterno come IP interlo, sentitevi liberi di cambiare come volete (in caso di mancata connessione ad internet)
if (strlen(g_szExternPublicIP) < 1)
{
#if defined(_MSC_VER) && _MSC_VER > 1500
    strcpy_s(g_szExternPublicIP, _countof(g_szExternPublicIP),g_szInternalIP);
#else
    strcpy(g_szExternPublicIP,g_szInternalIP);
#endif
}
#endif

/etc/rc.d/netif restart è molto FreeBSD 7, su FreeBSD nuovi puoi usare semplicemente service netif restart.
Non è richiesto il reboot perchè riavviamo già la rete con netif.

Il resto mi sembra tutto ok. Saluti.

Ti ringrazio veramente tanto per il tempo che hai speso. Ciò che hai scritto va ben oltre le mie capacità, pertanto per il momento mi limiterò a notificare la presenza della tua miglioria nella guida principale, per poi migliorare la stessa in futuro, quando avrò voglia di impratichirmi di più. Sono sicuro che comunque saranno in molti a sfruttare questo codice che hai rilasciato, per i motivi da te elencati (portabilità e considerazione dell'eventualità in locale).
 
Giorno ragazzi, ho cercato di seguire questa guida nella maniera più fedele possibile ma nel momento in cui avvio il server ho questo errore:
36888

Mentre per quanto riguarda il Sysser del channel 1 ad esempio ho questa serie di errori:
36889


Qualcuno ci è già passato? non ho la benchè minima idea di come risolvere questo problema, accetto qualsiasi consiglio o dritta.
Grazie in anticipo, saluti.
 
Probabilmente la tua server machine non ha accesso a internet, e per questo motivo non rileva l'IP tramite curl.
Per sapere se ho ragione basta provare a pingare google.
Codice:
ping -c 10 8.8.8.8
Se ti da 100% packets lost vuol dire che non hai internet sulla macchina
Ti ringrazio per aver preso visione del problema e devo dire che c'è una latenza allucinante però non ho nessuna perdita di pacchetti, (solitamente non laggo così tanto quindi è strana tutta questa latenza) in ogni caso quando ho dato quel comando il messaggio di risposta è stato questo:
36891
 
Il tuo g_szInternalIP è nullo (lo dice nell'errore che hai postato, è impostato su 0) devi verificare cosa è successo in config.cpp nei pressi dei punto modificati nella guida, probabilmente hai toccato qualcosa che non dovevi, nel senso che forse hai tolto un pezzo di codice pensando dovessi sostituire.
Se hai backuppato prima di seguire la guida ti consiglio di ripartire dal backup e rifare i passaggi stando più attento, altrimenti puoi postare il tuo config.cpp e desc_client.cpp sotto tag codice e spoiler cosi da farmi dare un occhiata (meglio ancora se usi pastebin)
Ho rifatto i vari procedimento da capo, lascio dunque qui sotto i vari file che ho modificato.
Il mio dubbio è sul config.cpp perchè i miei "3 pezzi dello script" sono diversi rispetto a questi della guida, non capendone molto mi sono limitato a non toccarli e aggiungere solamente il pezzo finale, ovvero:

36892


config.cpp
service.h
config.h
desc_client.cpp
 
C++:
//search:

        if (g_szPublicIP[0] == '0')
        {
            strlcpy(g_szPublicIP, netip, sizeof(g_szPublicIP));
            fprintf(stderr, "PUBLIC_IP: %s interface %s\n", netip, ifap->ifa_name);
        }

//new line and add:
        strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
Grazie mille, ho aggiunto la riga di codice che mi hai suggerito ed il server ora parte senza dare alcun problema, vedo inoltre anche le righe di avvio che cita la guida.
Ovvero:
36895


Però nel momento in cui provo a loggare il pg al caricamento per entrare nel mondo di gioco, mi riporta alla schermata di selezione server e channel, ho controllato sysser client e server ma non mi da alcun tipo di errore. Idee?
 
Grazie mille, ho aggiunto la riga di codice che mi hai suggerito ed il server ora parte senza dare alcun problema, vedo inoltre anche le righe di avvio che cita la guida.
Ovvero:
Visualizza allegato 36895

Però nel momento in cui provo a loggare il pg al caricamento per entrare nel mondo di gioco crasha, ho controllato sysser client e server ma non mi da alcun tipo di errore. Idee?

Prof. Oak : c'è un tempo e un luogo per ogni cosa Pervertito, ma non ora.

Questa volta il problema probabilmente non riguarda questa guida.
Apri una discussione in Help Dev, anche se rischi che ti ignoro come successo per quella in cui hai postato questo errore, scusami ma la pressione quando devo confrontarmi con i TOP DEV che ti hanno risposto lì era troppo alta. Mi sentivo un Niub.

good luck