/** \brief Receives a packet directly from the network interface and * filter its address. * Receive a packet whithout ENet processing it. Checks that the * sender of the packet is the one that corresponds to the sender * parameter. Does not check the port right now. * \param buffer A buffer to receive the data in. * \param buf_len Length of the buffer. * \param[out] sender : Transport address of the original sender of the * wanted packet. If the ip address is 0, do not check * the sender's ip address, otherwise wait till a message * from the specified sender arrives. All other messages * are discarded. * \param max_tries : Number of times we try to read data from the * socket. This is aproximately the time we wait in * milliseconds. -1 means eternal tries. * \return Length of the received data, or -1 if no data was received. */ int Network::receiveRawPacket(char *buffer, int buf_len, TransportAddress *sender, int max_tries) { memset(buffer, 0, buf_len); struct sockaddr_in addr; socklen_t from_len = sizeof(addr); int len = recvfrom(m_host->socket, buffer, buf_len, 0, (struct sockaddr*)(&addr), &from_len ); int count = 0; // wait to receive the message because enet sockets are non-blocking while(len < 0 && (count<max_tries || max_tries==-1) ) { count++; StkTime::sleep(1); // wait 1 millisecond between two checks len = recvfrom(m_host->socket, buffer, buf_len, 0, (struct sockaddr*)(&addr), &from_len); } // No message received if(len<0) return -1; Network::logPacket(NetworkString(std::string(buffer, len)), true); sender->setIP(ntohl((uint32_t)(addr.sin_addr.s_addr)) ); sender->setPort( ntohs(addr.sin_port) ); if (addr.sin_family == AF_INET) { Log::info("Network", "IPv4 Address of the sender was %s", sender->toString().c_str()); } return len; } // receiveRawPacket
Event::Event(ENetEvent* event) { switch (event->type) { case ENET_EVENT_TYPE_CONNECT: type = EVENT_TYPE_CONNECTED; break; case ENET_EVENT_TYPE_DISCONNECT: type = EVENT_TYPE_DISCONNECTED; break; case ENET_EVENT_TYPE_RECEIVE: type = EVENT_TYPE_MESSAGE; break; case ENET_EVENT_TYPE_NONE: return; break; } if (type == EVENT_TYPE_MESSAGE) { m_data = NetworkString(std::string((char*)(event->packet->data), event->packet->dataLength-1)); } m_packet = NULL; if (event->packet) m_packet = event->packet; if (m_packet) enet_packet_destroy(m_packet); // we got all we need, just remove the data. m_packet = NULL; std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers(); peer = new STKPeer*; *peer = NULL; for (unsigned int i = 0; i < peers.size(); i++) { if (peers[i]->m_peer == event->peer) { *peer = peers[i]; Log::verbose("Event", "The peer you sought has been found on %lx", (long int)(peer)); return; } } if (*peer == NULL) // peer does not exist, create him { STKPeer* new_peer = new STKPeer(); new_peer->m_peer = event->peer; *peer = new_peer; Log::debug("Event", "Creating a new peer, address are STKPeer:%lx, Peer:%lx", (long int)(new_peer), (long int)(event->peer)); } }
/** \brief Sends a packet whithout ENet adding its headers. * This function is used in particular to achieve the STUN protocol. * \param data : Data to send. * \param length : Length of the sent data. * \param dst : Destination of the packet. */ void Network::sendRawPacket(uint8_t* data, int length, const TransportAddress& dst) { struct sockaddr_in to; int to_len = sizeof(to); memset(&to,0,to_len); to.sin_family = AF_INET; to.sin_port = htons(dst.getPort()); to.sin_addr.s_addr = htonl(dst.getIP()); sendto(m_host->socket, (char*)data, length, 0,(sockaddr*)&to, to_len); Log::verbose("Network", "Raw packet sent to %s", dst.toString().c_str()); Network::logPacket(NetworkString(std::string((char*)(data), length)), false); } // sendRawPacket