Esempio n. 1
0
void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
	
	bool outgoing_data = HasOutgoingData();	//up here to avoid recursive locking
	
	EQStreamState orig_state = GetState();
	if (orig_state == CLOSING && !outgoing_data) {
		_log(NET__NET_TRACE, _L "Out of data in closing state, disconnecting." __L);
		_SendDisconnect();
		SetState(DISCONNECTING);
	} else if (LastPacket && (now-LastPacket) > timeout) {
		switch(orig_state) {
		case CLOSING:
			//if we time out in the closing state, they are not acking us, just give up
			_log(NET__DEBUG, _L "Timeout expired in closing state. Moving to closed state." __L);
			_SendDisconnect();
			SetState(CLOSED);
			break;
		case DISCONNECTING:
			//we timed out waiting for them to send us the disconnect reply, just give up.
			_log(NET__DEBUG, _L "Timeout expired in disconnecting state. Moving to closed state." __L);
			SetState(CLOSED);
			break;
		case CLOSED:
			_log(NET__DEBUG, _L "Timeout expired in closed state??" __L);
			break;
		case ESTABLISHED:
			//we timed out during normal operation. Try to be nice about it.
			//we will almost certainly time out again waiting for the disconnect reply, but oh well.
			_log(NET__DEBUG, _L "Timeout expired in established state. Closing connection." __L);
			_SendDisconnect();
			SetState(DISCONNECTING);
		}
	}
}
Esempio n. 2
0
void EQStream::Close() {
	if(HasOutgoingData()) {
		//there is pending data, wait for it to go out.
		Log.Out(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L);
		SetState(CLOSING);
	} else {
		//otherwise, we are done, we can drop immediately.
		_SendDisconnect();
		Log.Out(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L);
		SetState(DISCONNECTING);
	}
}
Esempio n. 3
0
void EQStream::AdjustRates(uint32 average_delta)
{
#ifdef RETRANSMITS
	if (average_delta && (average_delta <= RuleI(EQStream, AverageDeltaMax))) {
#else
	if (average_delta) {
#endif
		MRate.lock();
		RateThreshold=RATEBASE/average_delta;
		DecayRate=DECAYBASE/average_delta;
		_log(NET__RATES, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, RateThreshold, DecayRate, average_delta);
		MRate.unlock();
#ifdef RETRANSMITS
	} else {
		_log(NET__RATES, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L, average_delta, RuleI(EQStream, AverageDeltaMax));
#endif
	}
}

void EQStream::Close() {
	if(HasOutgoingData()) {
		//there is pending data, wait for it to go out.
		_log(NET__DEBUG, _L "Stream requested to Close(), but there is pending data, waiting for it." __L);
		SetState(CLOSING);
	} else {
		//otherwise, we are done, we can drop immediately.
		_SendDisconnect();
		_log(NET__DEBUG, _L "Stream closing immediate due to Close()" __L);
		SetState(DISCONNECTING);
	}
}


//this could be expanded to check more than the fitst opcode if
//we needed more complex matching
EQStream::MatchState EQStream::CheckSignature(const Signature *sig) {
	EQRawApplicationPacket *p = NULL;
	MatchState res = MatchNotReady;
	
	MInboundQueue.lock();
	if (!InboundQueue.empty()) {
		//this is already getting hackish...
		p = InboundQueue.front();
		if(sig->ignore_eq_opcode != 0 && p->opcode == sig->ignore_eq_opcode) {
			if(InboundQueue.size() > 1) {
				p = InboundQueue[1];
			} else {
				p = NULL;
			}
		}
		if(p == NULL) {
			//first opcode is ignored, and nothing else remains... keep waiting
		} else if(p->opcode == sig->first_eq_opcode) {
			//opcode matches, check length..
			if(p->size == sig->first_length) {
				_log(NET__IDENT_TRACE, "%s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
				res = MatchSuccessful;
			} else if(sig->first_length == 0) {
				_log(NET__IDENT_TRACE, "%s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
				res = MatchSuccessful;
			} else {
				//opcode matched but length did not.
				_log(NET__IDENT_TRACE, "%s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
				res = MatchFailed;
			}
		} else {
			//first opcode did not match..
			_log(NET__IDENT_TRACE, "%s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
			res = MatchFailed;
		}
	}
	MInboundQueue.unlock();
	
	return(res);
}