- updated FTP code to use specific ports for MG and not random FTP ports

This commit is contained in:
Mark Vejvoda
2011-01-06 00:52:00 +00:00
parent b5dd9591da
commit a5a744fcad
12 changed files with 167 additions and 47 deletions

View File

@@ -227,7 +227,8 @@ LOCAL int ftpCmdPort(int sessionId, const char* args, int len)
{
ftpCloseSocket(ftpGetSession(sessionId)->passiveDataSocket);
ftpGetSession(sessionId)->passiveDataSocket = -1;
}
}
//ftpGetSession(sessionId)->passiveDataSocket = -1;
ftpGetSession(sessionId)->remoteDataPort = clientPort;
ftpGetSession(sessionId)->passive = FALSE;
ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg007);
@@ -419,7 +420,7 @@ LOCAL int ftpCmdList(int sessionId, const char* args, int len)
if(ftpGetSession(sessionId)->passive == FALSE)
{
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort);
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId);
if(s < 0)
{
ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011);
@@ -454,7 +455,7 @@ LOCAL int ftpCmdNlst(int sessionId, const char* args, int len)
if(ftpGetSession(sessionId)->passive == FALSE)
{
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort);
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId);
if(s < 0)
{
ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011);
@@ -497,7 +498,7 @@ if(VERBOSE_MODE_ENABLED) printf("stat() = %d fileInfo.type = %d\n", statResult,f
if(ftpGetSession(sessionId)->passive == FALSE)
{
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort);
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId);
if(s < 0)
{
ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011);
@@ -539,7 +540,7 @@ LOCAL int ftpCmdStor(int sessionId, const char* args, int len)
if(ftpGetSession(sessionId)->passive == FALSE)
{
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort);
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId);
if(s < 0)
{
ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011);
@@ -662,8 +663,9 @@ LOCAL int ftpCmdPasv(int sessionId, const char* args, int len)
{
ftpCloseSocket(ftpGetSession(sessionId)->passiveDataSocket);
ftpGetSession(sessionId)->passiveDataSocket = -1;
}
s = ftpEstablishDataConnection(TRUE, &ip, &port);
}
//ftpGetSession(sessionId)->passiveDataSocket = -1;
s = ftpEstablishDataConnection(TRUE, &ip, &port,sessionId);
if(s < 0)
{
ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012);
@@ -680,7 +682,7 @@ if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, client IP = %u, r
if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, adding UPNP port forward\n", sessionId);
ftpAddUPNPPortForward(port, port);
//ftpAddUPNPPortForward(port, port);
remoteFTPServerIp = ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp);
@@ -805,7 +807,7 @@ LOCAL int ftpCmdMlsd(int sessionId, const char* args, int len)
if(ftpGetSession(sessionId)->passive == FALSE)
{
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort);
s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId);
if(s < 0)
{
ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011);

View File

@@ -34,13 +34,31 @@
/**
* @brief server-sockets that listens for incoming connections
*/
LOCAL socket_t server;
LOCAL socket_t server;
LOCAL int serverListenPort;
LOCAL int serverPassiveListenPort;
//LOCAL socket_t serverPassivePort;
void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3) {
ftpFindExternalFTPServerIp = cb1;
ftpAddUPNPPortForward = cb2;
ftpRemoveUPNPPortForward = cb3;
}
int ftpGetListenPort()
{
return serverListenPort;
}
int ftpGetPassivePort()
{
return serverPassiveListenPort;
}
//socket_t ftpGetServerPassivePortListenSocket()
//{
// return serverPassivePort;
//}
/**
* @brief Initializes and starts the server
@@ -50,8 +68,11 @@ void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2,
* - -1: could not create server socket
*/
int ftpStart(int portNumber)
{
server = -1; // set server socket to invalid value
{
serverListenPort = portNumber;
serverPassiveListenPort = portNumber + 1;
server = -1; // set server socket to invalid value
//serverPassivePort = -1;
if(VERBOSE_MODE_ENABLED) printf("Feathery FTP-Server\n");
@@ -59,7 +80,7 @@ if(VERBOSE_MODE_ENABLED) printf("Feathery FTP-Server\n");
if(VERBOSE_MODE_ENABLED) printf("Creating server socket");
server = ftpCreateServerSocket(portNumber); // create main listener socket
server = ftpCreateServerSocket(serverListenPort); // create main listener socket
if(server < 0)
{
if(VERBOSE_MODE_ENABLED) printf("\t\terror\n");
@@ -70,7 +91,24 @@ if(VERBOSE_MODE_ENABLED) printf("\t\terror\n");
if(VERBOSE_MODE_ENABLED) printf("\t\tok\n");
if(VERBOSE_MODE_ENABLED) printf("Server successfully started\n");
ftpTrackSocket(server); // add socket to "watchlist"
ftpTrackSocket(server); // add socket to "watchlist"
/*
if(VERBOSE_MODE_ENABLED) printf("Creating server PASSIVE socket");
serverPassivePort = ftpCreateServerSocket(serverPassiveListenPort); // create main listener socket
if(serverPassivePort < 0)
{
if(VERBOSE_MODE_ENABLED) printf("\t\tpassive port error\n");
return -1;
}
if(VERBOSE_MODE_ENABLED) printf("\t\tok\n");
if(VERBOSE_MODE_ENABLED) printf("Server passive port successfully started\n");
*/
return 0;
}
@@ -198,13 +236,14 @@ int ftpShutdown(void)
{
int n;
ftpUntrackSocket(server);
ftpCloseSocket(server);
ftpCloseSocket(server);
//ftpCloseSocket(serverPassivePort);
for(n = 0; n < MAX_CONNECTIONS; n++)
{
if(ftpGetSession(n)->open)
{
ftpUntrackSocket(ftpGetSession(n)->ctrlSocket);
ftpUntrackSocket(ftpGetSession(n)->ctrlSocket);
}
ftpCloseSession(n);
}

View File

@@ -128,16 +128,21 @@ if(VERBOSE_MODE_ENABLED) printf("In ftpCloseSession sessionId = %d, remote IP =
{
if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, removing UPNP port forward [%d]\n", id,sessions[id].remoteFTPServerPassivePort);
ftpRemoveUPNPPortForward(sessions[id].remoteFTPServerPassivePort, sessions[id].remoteFTPServerPassivePort);
//ftpRemoveUPNPPortForward(sessions[id].remoteFTPServerPassivePort, sessions[id].remoteFTPServerPassivePort);
sessions[id].remoteFTPServerPassivePort = 0;
}
}
if(sessions[id].open) {
ftpCloseSocket(sessions[id].ctrlSocket);
ftpCloseTransmission(id);
ftpCloseTransmission(id);
if(sessions[id].passiveDataSocket > 0)
{
ftpCloseSocket(sessions[id].passiveDataSocket);
}
}
sessions[id].remoteIp = 0;
sessions[id].ctrlSocket = 0;
sessions[id].ctrlSocket = 0;
sessions[id].passiveDataSocket = 0;
sessions[id].open = FALSE;
if(VERBOSE_MODE_ENABLED) printf("Session %d closed\n", id);

View File

@@ -178,7 +178,8 @@ int ftpRemoveDir(const char* path)
}
int ftpCloseSocket(socket_t s)
{
{
if(VERBOSE_MODE_ENABLED) printf("\nClosing socket: %d\n",s);
return close(s);
}
@@ -207,7 +208,7 @@ int ftpReceive(socket_t s, void *data, int len)
return recv(s, data, len, 0);
}
socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port)
socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int sessionId)
{
socket_t dataSocket;
struct sockaddr_in clientAddr;
@@ -243,15 +244,28 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port)
}
}
else
{
{
int passivePort = ftpGetPassivePort() + sessionId;
if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d\n",sessionId,passivePort);
myAddr.sin_family = AF_INET;
myAddr.sin_addr.s_addr = INADDR_ANY;
myAddr.sin_port = htons(0);
myAddr.sin_port = htons(passivePort);
//myAddr.sin_port = htons(ftpGetPassivePort() + sessionId);
int val = 1;
setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr)))
{
close(dataSocket);
if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d FAILED: %d\n",sessionId,passivePort,dataSocket);
close(dataSocket);
return -1;
}
}
if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok\n",sessionId,passivePort);
len = sizeof(myAddr);
if(getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln
{
@@ -261,12 +275,20 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port)
*port = ntohs(myAddr.sin_port);
*ip = ownIp;
if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d about to listen on port: %d using listener socket: %d\n",sessionId,passivePort,*port,dataSocket);
if(listen(dataSocket, 1))
{
{
if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d FAILED #2: %d\n",sessionId,passivePort,dataSocket);
close(dataSocket);
return -1;
}
}
//*port = ftpGetPassivePort();
//*ip = ownIp;
//dataSocket = ftpGetServerPassivePortListenSocket();
}
return dataSocket;
}
@@ -291,7 +313,8 @@ socket_t ftpCreateServerSocket(int portNumber)
{
int theServer;
struct sockaddr_in serverinfo;
unsigned len;
unsigned len;
int val = 1;
theServer = socket(AF_INET, SOCK_STREAM, 0);
if(theServer < 0)
@@ -301,6 +324,8 @@ socket_t ftpCreateServerSocket(int portNumber)
serverinfo.sin_addr.s_addr = INADDR_ANY;
serverinfo.sin_port = htons(portNumber);
len = sizeof(serverinfo);
setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
if(bind(theServer, (struct sockaddr *)&serverinfo, len))
{
@@ -308,7 +333,7 @@ socket_t ftpCreateServerSocket(int portNumber)
return -2;
}
if(listen(theServer, 3))
if(listen(theServer, 16))
{
ftpCloseSocket(theServer);
return -3;

View File

@@ -237,7 +237,7 @@ int ftpReceive(socket_t s, void *data, int len)
return recv(s, data, len, 0);
}
socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port)
socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int sessionId)
{
SOCKET dataSocket;
struct sockaddr_in clientAddr;
@@ -257,7 +257,8 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port)
}
myAddr.sin_family = AF_INET;
myAddr.sin_addr.s_addr = INADDR_ANY;
myAddr.sin_port = htons(20);
myAddr.sin_port = htons(20);
if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr)))
{
closesocket(dataSocket);
@@ -273,10 +274,15 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port)
}
}
else
{
{
myAddr.sin_family = AF_INET;
myAddr.sin_addr.s_addr = INADDR_ANY;
myAddr.sin_port = htons(0);
//myAddr.sin_port = htons(0);
myAddr.sin_port = htons(ftpGetPassivePort() + sessionId);
int val = 1;
setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr)))
{
closesocket(dataSocket);
@@ -296,7 +302,11 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port)
{
closesocket(dataSocket);
return -1;
}
}
//*port = ftpGetPassivePort();
//*ip = ownIp;
//dataSocket = ftpGetServerPassivePortListenSocket();
}
return (socket_t)dataSocket;
}
@@ -333,11 +343,7 @@ socket_t ftpCreateServerSocket(int portNumber)
serverinfo.sin_port = htons(portNumber);
len = sizeof(serverinfo);
#ifndef WIN32
setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
#else
setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
#endif
if(bind(theServer, (struct sockaddr *)&serverinfo, len))
{
@@ -345,7 +351,7 @@ socket_t ftpCreateServerSocket(int portNumber)
return -2;
}
if(listen(theServer, 3))
if(listen(theServer, 16))
{
ftpCloseSocket(theServer);
return -3;

View File

@@ -36,17 +36,22 @@ ip_t FindExternalFTPServerIp(ip_t clientIp) {
return result;
}
FTPServerThread::FTPServerThread(std::pair<string,string> mapsPath,std::pair<string,string> tilesetsPath, int portNumber) : BaseThread() {
FTPServerThread::FTPServerThread(std::pair<string,string> mapsPath,std::pair<string,string> tilesetsPath, int portNumber, int maxPlayers) : BaseThread() {
this->mapsPath = mapsPath;
this->tilesetsPath = tilesetsPath;
this->portNumber = portNumber;
this->maxPlayers = maxPlayers;
ftpInit(&FindExternalFTPServerIp,&UPNP_Tools::AddUPNPPortForward,&UPNP_Tools::RemoveUPNPPortForward);
VERBOSE_MODE_ENABLED = SystemFlags::VERBOSE_MODE_ENABLED;
}
FTPServerThread::~FTPServerThread() {
// Remove any UPNP port forwarded ports
UPNP_Tools::upnp_rem_redirect(ServerSocket::getFTPServerPort());
for(int clientIndex = 1; clientIndex <= maxPlayers; ++clientIndex) {
UPNP_Tools::upnp_rem_redirect(ServerSocket::getFTPServerPort() + clientIndex);
}
}
void FTPServerThread::signalQuit() {

View File

@@ -63,6 +63,7 @@ namespace Shared{ namespace Platform{
int Socket::broadcast_portno = 61357;
int ServerSocket::ftpServerPort = 61358;
int ServerSocket::maxPlayerCount = -1;
int ServerSocket::externalPort = Socket::broadcast_portno;
BroadCastClientSocketThread *ClientSocket::broadCastClientThread = NULL;
@@ -1875,8 +1876,24 @@ void ServerSocket::UPNPInitStatus(bool result) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result);
if(result == true) {
int ports[4] = { this->getExternalPort(), this->getBindPort(), this->getFTPServerPort(), this->getFTPServerPort() };
UPNP_Tools::NETaddRedirects(ports);
//int ports[4] = { this->getExternalPort(), this->getBindPort(), this->getFTPServerPort(), this->getFTPServerPort() };
std::vector<int> UPNPPortForwardList;
// Glest Game Server port
UPNPPortForwardList.push_back(this->getExternalPort());
UPNPPortForwardList.push_back(this->getBindPort());
// Glest mini FTP Server Listen Port
UPNPPortForwardList.push_back(this->getFTPServerPort());
UPNPPortForwardList.push_back(this->getFTPServerPort());
// GLest mini FTP Server Passive file TRansfer ports (1 per game player)
for(int clientIndex = 1; clientIndex <= ServerSocket::maxPlayerCount; ++clientIndex) {
UPNPPortForwardList.push_back(this->getFTPServerPort() + clientIndex);
UPNPPortForwardList.push_back(this->getFTPServerPort() + clientIndex);
}
UPNP_Tools::NETaddRedirects(UPNPPortForwardList);
}
}
@@ -2023,13 +2040,25 @@ void UPNP_Tools::upnp_rem_redirect(int ext_port) {
UPNP_DeletePortMapping(urls.controlURL, data.servicetype, ext_port_str, "TCP", 0);
}
void UPNP_Tools::NETaddRedirects(int ports[4]) {
void UPNP_Tools::NETaddRedirects(std::vector<int> UPNPPortForwardList) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_rem_redir(%d)\n",__FILE__,__FUNCTION__,__LINE__);
if(UPNPPortForwardList.size() % 2 != 0) {
// We need groups of 2 ports.. one external and one internal for opening ports on UPNP router
throw runtime_error("UPNPPortForwardList.size() MUST BE divisable by 2");
}
for(int clientIndex = 0; clientIndex < UPNPPortForwardList.size(); clientIndex += 2) {
int ports[2] = { UPNPPortForwardList[clientIndex], UPNPPortForwardList[clientIndex+1] };
upnp_add_redirect(ports);
}
/*
int portsA[2] = { ports[0], ports[1] };
upnp_add_redirect(portsA);
int portsB[2] = { ports[2], ports[3] };
upnp_add_redirect(portsB);
*/
}
void UPNP_Tools::NETremRedirects(int ext_port) {