Fixed a performance issue involving std::string and EQStream identification.

Fixed a denial-of-service exploit in EQStream.
This commit is contained in:
SecretsOTheP 2014-02-15 23:50:32 -05:00
parent 46f8723314
commit 1ebf88abbb
3 changed files with 11 additions and 10 deletions

View File

@ -144,7 +144,8 @@ void EQStreamFactory::Push(EQStream *s)
void EQStreamFactory::ReaderLoop()
{
fd_set readset;
std::map<std::string,EQStream *>::iterator stream_itr;
std::map<std::pair<uint32, uint16>,EQStream *>::iterator stream_itr;
EQStream* currStream = NULL;
int num;
int length;
unsigned char buffer[2048];
@ -183,14 +184,13 @@ timeval sleep_time;
{
// What do we wanna do?
} else {
char temp[25];
sprintf(temp,"%u.%d",ntohl(from.sin_addr.s_addr),ntohs(from.sin_port));
MStreams.lock();
if ((stream_itr=Streams.find(temp))==Streams.end()) {
stream_itr=Streams.find(std::make_pair(from.sin_addr.s_addr, from.sin_port));
if (stream_itr == Streams.end()) {
if (buffer[1]==OP_SessionRequest) {
EQStream *s = new EQStream(from);
s->SetStreamType(StreamType);
Streams[temp]=s;
Streams[std::make_pair(from.sin_addr.s_addr, from.sin_port)]=s;
WriterWork.Signal();
Push(s);
s->AddBytesRecv(length);
@ -225,7 +225,7 @@ void EQStreamFactory::CheckTimeout()
MStreams.lock();
unsigned long now=Timer::GetCurrentTime();
std::map<std::string,EQStream *>::iterator stream_itr;
std::map<std::pair<uint32, uint16>,EQStream *>::iterator stream_itr;
for(stream_itr=Streams.begin();stream_itr!=Streams.end();) {
EQStream *s = stream_itr->second;
@ -241,7 +241,7 @@ void EQStreamFactory::CheckTimeout()
} else {
//everybody is done, we can delete it now
//std::cout << "Removing connection" << std::endl;
std::map<std::string,EQStream *>::iterator temp=stream_itr;
std::map<std::pair<uint32, uint16>,EQStream *>::iterator temp=stream_itr;
stream_itr++;
//let whoever has the stream outside delete it
delete temp->second;
@ -257,7 +257,7 @@ void EQStreamFactory::CheckTimeout()
void EQStreamFactory::WriterLoop()
{
std::map<std::string,EQStream *>::iterator stream_itr;
std::map<std::pair<uint32, uint16>,EQStream *>::iterator stream_itr;
bool havework=true;
std::vector<EQStream *> wants_write;
std::vector<EQStream *>::iterator cur,end;
@ -292,7 +292,7 @@ Timer DecayTimer(20);
//bullshit checking, to see if this is really happening, GDB seems to think so...
if(stream_itr->second == nullptr) {
fprintf(stderr, "ERROR: nullptr Stream encountered in EQStreamFactory::WriterLoop for: %s", stream_itr->first.c_str());
fprintf(stderr, "ERROR: nullptr Stream encountered in EQStreamFactory::WriterLoop for: %i", stream_itr->first.first, stream_itr->first.second);
continue;
}

View File

@ -27,7 +27,7 @@ class EQStreamFactory : private Timeoutable {
std::queue<EQStream *> NewStreams;
Mutex MNewStreams;
std::map<std::string,EQStream *> Streams;
std::map<std::pair<uint32, uint16>,EQStream *> Streams;
Mutex MStreams;
virtual void CheckTimeout();

View File

@ -56,6 +56,7 @@ void EQStreamIdentifier::Process() {
//if stream hasn't finished initializing then continue;
if(r->stream->GetState() == UNESTABLISHED)
{
cur++;
continue;
}
if(r->stream->GetState() != ESTABLISHED) {