Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Closed Thread
 
Thread Tools Display Modes
  #1  
Old 03-24-2008, 06:48 PM
TheLieka
Developer
 
Join Date: Oct 2004
Location: THE ATL (wut wut)
Posts: 325
Default Limiting client connections by IP address (Integrated into Rules System)

I've seen several people asking / talking about limiting client connections by IP address lately, so I figure I'd just post my implementation of it. Give it a try and let me know what you think.

.\common\ruletypes.h


Change:
Code:
RULE_CATEGORY( World )
RULE_INT ( World, ZoneAutobootTimeoutMS, 60000 )
RULE_INT ( World, ClientKeepaliveTimeoutMS, 65000 )
RULE_CATEGORY_END()
To:
Code:
RULE_CATEGORY( World )
RULE_INT ( World, ZoneAutobootTimeoutMS, 60000 )
RULE_INT ( World, ClientKeepaliveTimeoutMS, 65000 )
RULE_INT ( World, MaxClientsPerIP, -1 ) //Lieka Edit: Maximum number of clients allowed to connect per IP address.  Default value: -1 (feature disabled)
RULE_INT ( World, ExemptMaxClientsStatus, -1 ) //Lieka Edit: Exempt accounts from the MaxClientsPerIP rule, if their status is >= this value.  Default value: -1 (feature disabled)
RULE_CATEGORY_END()

.\world\clientlist.h


Change:
Code:
void	ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* scl);
void	CLERemoveZSRef(ZoneServer* iZS);
ClientListEntry* CheckAuth(int32 iLSID, const char* iKey);
ClientListEntry* CheckAuth(const char* iName, const char* iPassword);
ClientListEntry* CheckAuth(int32 id, const char* iKey, int32 ip);
ClientListEntry* FindCharacter(const char* name);
ClientListEntry* FindCLEByAccountID(int32 iAccID);
ClientListEntry* FindCLEByCharacterID(int32 iAccID);
ClientListEntry* GetCLE(int32 iID);
void	CLCheckStale();
void	CLEKeepAlive(int32 numupdates, int32* wid);
void	CLEAdd(int32 iLSID, const char* iLoginName, const char* iLoginKey, sint16 iWorldAdmin = 0, int32 ip = 0, uint8 local=0);
void	UpdateClientGuild(int32 char_id, int32 guild_id);
To:

Code:
void	ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* scl);
void	CLERemoveZSRef(ZoneServer* iZS);
ClientListEntry* CheckAuth(int32 iLSID, const char* iKey);
ClientListEntry* CheckAuth(const char* iName, const char* iPassword);
ClientListEntry* CheckAuth(int32 id, const char* iKey, int32 ip);
ClientListEntry* FindCharacter(const char* name);
ClientListEntry* FindCLEByAccountID(int32 iAccID);
ClientListEntry* FindCLEByCharacterID(int32 iAccID);
ClientListEntry* GetCLE(int32 iID);
void	GetCLEIP(int32 iIP);
void	CLCheckStale();
void	CLEKeepAlive(int32 numupdates, int32* wid);
void	CLEAdd(int32 iLSID, const char* iLoginName, const char* iLoginKey, sint16 iWorldAdmin = 0, int32 ip = 0, uint8 local=0);
void	UpdateClientGuild(int32 char_id, int32 guild_id);
.\world\clientlist.cpp

After:
Code:
void ClientList::CLERemoveZSRef(ZoneServer* iZS) {
	LinkedListIterator<ClientListEntry*> iterator(clientlist);

	iterator.Reset();
	while(iterator.MoreElements()) {
		if (iterator.GetData()->Server() == iZS) {
			iterator.GetData()->ClearServer(); // calling this before LeavingZone() makes CLE not update the number of players in a zone
			iterator.GetData()->LeavingZone();
		}
		iterator.Advance();
	}
}

ClientListEntry* ClientList::GetCLE(int32 iID) {
	LinkedListIterator<ClientListEntry*> iterator(clientlist);


	iterator.Reset();
	while(iterator.MoreElements()) {
		if (iterator.GetData()->GetID() == iID) {
			return iterator.GetData();
		}
		iterator.Advance();
	}
	return 0;
}
Add:
Code:
 //Lieka Edit Begin:  Check current CLE Entry IPs against incoming connection

void ClientList::GetCLEIP(int32 iIP) {
	ClientListEntry* countCLEIPs = 0;
	LinkedListIterator<ClientListEntry*> iterator(clientlist);

	int IPInstances = 0;
	iterator.Reset();
	while(iterator.MoreElements()) {
		countCLEIPs = iterator.GetData();
		if ((countCLEIPs->GetIP() == iIP) && ((countCLEIPs->Admin() <= (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0)) {
			IPInstances++;
			if (IPInstances > (RuleI(World, MaxClientsPerIP)){
				countCLEIPs->SetOnline(CLE_Status_Offline);
				iterator.RemoveCurrent();
			}
		}
		iterator.Advance();
	}
}
//Lieka Edit End

.\world\client.cpp


After:
Code:
		case OP_EnterWorld: // Enter world
		{
			if (GetAccountID() == 0) {
				clog(WORLD__CLIENT_ERR,"Enter world with no logged in account");
				eqs->Close();
				break;
			}
			if(GetAdmin() < 0)
			{
				clog(WORLD__CLIENT,"Account banned or suspended.");
				eqs->Close();
				break;
			}
Add:
Code:

if (RuleI(World, MaxClientsPerIP) >= 0) {
client_list.GetCLEIP(this->GetIP());  //Lieka Edit Begin:  Check current CLE Entry IPs against incoming connection
}
Required SQL:
Code:
Insert into rule_values values (0, 'World:MaxClientsPerIP', -1);
Insert into rule_values values (0, 'World:ExemptMaxClientsStatus', -1);
There are 2 new rule values.
World:MaxClientsPerIP = Maximum number of simultaneous EQ Client connections allowed per IP address. Set the rule value to -1 to disable this feature.
World:ExemptMaxClientsStatus = Minimum Account status to exempt the MaxClientsPerIP rule. This is helpful for the inevitable random family of 16 that live together, and all want to play on your server, as well as GMs, Devs, and QA staff. Again, set the rule value to -1 to disable this feature.

It's commented throughout, but let me know if you have questions.

Thanks,
Dax
__________________
Daxum



Former ServerOp - Vallon Zek / Tallon Zek Emu Server - Legit / Guild PvP - (2007 - 2011 RIP)

Last edited by KLS; 06-15-2008 at 01:08 PM..
  #2  
Old 03-25-2008, 06:03 AM
Semedaien
Sarnak
 
Join Date: Dec 2006
Posts: 68
Default

very much appreciated sir, will get back to you on how it works
  #3  
Old 03-25-2008, 08:33 AM
krusher
Sarnak
 
Join Date: Jan 2003
Location: Grand Rapids, MI
Posts: 90
Default Request

Would it now be possible to BAN by IP with some modifications to this code. I know we can ban by account name but it sure would be handy to have a table with banned IP's to check against the login process.

Thanks

Krusher
  #4  
Old 03-25-2008, 09:17 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Wow! This would be an awesome addition to the next patch update! *hint hint* Very nice work yet again!

If the new rules you have been making and the new stuff KLS has been working on all goes in, this will be the best code update in a while! Getting a little antsy

Also, the idea Krusher has is a great one too! You would need a new table for it to reference for IPs. But then again, I wouldn't mind having IP addresses listed in a new table that matches accounts to IPs. It would be awesome for keeping track of the "bad" players. As of now, I have to catch them when they are on and do a #iplookup. If this table was put in, you could then just have a field for blocking that IP. Maybe even a new in-game command #ipblock <IP Address>.

I have IP blockers and even some built into my router, but it would be nice if it could just be done directly from the server tables.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
  #5  
Old 03-25-2008, 06:23 PM
TheLieka
Developer
 
Join Date: Oct 2004
Location: THE ATL (wut wut)
Posts: 325
Default

I've been thinking about doing that for a while, but haven't gotten around to coding it. Right now we just ban IPs at the firewall when we need to, but being able to do it from within the database would be a pretty nice addition. I might just look into that.

Dax
__________________
Daxum



Former ServerOp - Vallon Zek / Tallon Zek Emu Server - Legit / Guild PvP - (2007 - 2011 RIP)
  #6  
Old 03-25-2008, 06:57 PM
MNWatchdog
Hill Giant
 
Join Date: Feb 2006
Posts: 179
Default

Thanks for your code Dax. I wish more people would post thier code changes for others who might want to integrate them.
  #7  
Old 03-25-2008, 07:03 PM
MNWatchdog
Hill Giant
 
Join Date: Feb 2006
Posts: 179
Default

Quote:
Originally Posted by krusher View Post
Would it now be possible to BAN by IP with some modifications to this code. I know we can ban by account name but it sure would be handy to have a table with banned IP's to check against the login process.

Thanks

Krusher
Sounds like a seed of a new thread.

Although, I think blocking at the router is probably a better idea. Dont even let them near your server. Keeps the vengeful hackers further away. Only down side is if your router either doesnt support this or you run out of blockable IPs in the router.
  #8  
Old 03-26-2008, 03:16 AM
Angelox
AX Classic Developer
 
Join Date: May 2006
Location: filler
Posts: 2,049
Default

You see, that's what I'm talking about!
Thanks for the fix, I hope we get it into the source soon
  #9  
Old 03-26-2008, 09:17 AM
Jibbatwinkers
Sarnak
 
Join Date: May 2006
Location: Cincinnati
Posts: 73
Default

Excited for this to go in, thanks for sharing!
__________________
Lead GM ~ Zeb
Zeb Server
ZebServer.com
  #10  
Old 03-26-2008, 11:27 AM
ChaosSlayer
Demi-God
 
Join Date: May 2007
Posts: 1,032
Default

/applauds

Boxers! Beware.. Mha-ha-ha-ha
  #11  
Old 03-26-2008, 06:17 PM
TheLieka
Developer
 
Join Date: Oct 2004
Location: THE ATL (wut wut)
Posts: 325
Default

Quote:
Originally Posted by krusher View Post
Would it now be possible to BAN by IP with some modifications to this code. I know we can ban by account name but it sure would be handy to have a table with banned IP's to check against the login process.

Thanks

Krusher
Try this out:

http://www.eqemulator.net/forums/showthread.php?t=24748
__________________
Daxum



Former ServerOp - Vallon Zek / Tallon Zek Emu Server - Legit / Guild PvP - (2007 - 2011 RIP)
  #12  
Old 04-02-2008, 06:03 PM
TheLieka
Developer
 
Join Date: Oct 2004
Location: THE ATL (wut wut)
Posts: 325
Default

I was double checking this submission against the current release, and saw that I had a couple of issues with it. Here are the corrections. Sorry about that.

This portion had a typo in it:
.\world\clientlist.cpp

After:

Code:
void ClientList::CLERemoveZSRef(ZoneServer* iZS) {
	LinkedListIterator<ClientListEntry*> iterator(clientlist);

	iterator.Reset();
	while(iterator.MoreElements()) {
		if (iterator.GetData()->Server() == iZS) {
			iterator.GetData()->ClearServer(); // calling this before LeavingZone() makes CLE not update the number of players in a zone
			iterator.GetData()->LeavingZone();
		}
		iterator.Advance();
	}
}

ClientListEntry* ClientList::GetCLE(int32 iID) {
	LinkedListIterator<ClientListEntry*> iterator(clientlist);


	iterator.Reset();
	while(iterator.MoreElements()) {
		if (iterator.GetData()->GetID() == iID) {
			return iterator.GetData();
		}
		iterator.Advance();
	}
	return 0;
}


Add:

Code:
 //Lieka Edit Begin:  Check current CLE Entry IPs against incoming connection

void ClientList::GetCLEIP(int32 iIP) {
	ClientListEntry* countCLEIPs = 0;
	LinkedListIterator<ClientListEntry*> iterator(clientlist);

	int IPInstances = 0;
	iterator.Reset();
	while(iterator.MoreElements()) {
		countCLEIPs = iterator.GetData();
		if ((countCLEIPs->GetIP() == iIP) && ((countCLEIPs->Admin() <= (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0))) {
			IPInstances++;
			if (IPInstances > (RuleI(World, MaxClientsPerIP))){
				countCLEIPs->SetOnline(CLE_Status_Offline);
				iterator.RemoveCurrent();
			}
		}
		iterator.Advance();
	}
}
//Lieka Edit End
I left this part out:
.\world\clientlist.h

After:

Code:
#include "../common/eq_packet_structs.h"
#include "../common/linked_list.h"
#include "../common/timer.h"
Add:
Code:
#include "../common/rulesys.h"
Dax
__________________
Daxum



Former ServerOp - Vallon Zek / Tallon Zek Emu Server - Legit / Guild PvP - (2007 - 2011 RIP)
  #13  
Old 04-07-2008, 03:30 PM
Angelox
AX Classic Developer
 
Join Date: May 2006
Location: filler
Posts: 2,049
Default

Please! I don't want to shut this thread down - post here only if you have a reasonable fix to this submission. Other than that, you can post comments here;
http://eqemulator.net/forums/showthr...t=24787&page=2
Again, this forum is intended for submissions only
Closed Thread


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 04:10 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3