+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
#include "connection.h"
#include "main.h"
#include "serialization.h"
address = a_address;
timeout_counter = 0.0;
//resend_timeout = RESEND_TIMEOUT_MINIMUM;
+ ping_timer = 0.0;
resend_timeout = 0.5;
avg_rtt = -1.0;
has_sent_with_id = false;
m_protocol_id = protocol_id;
m_max_packet_size = max_packet_size;
m_timeout = timeout;
- m_peer_id = PEER_ID_NEW;
+ m_peer_id = PEER_ID_INEXISTENT;
//m_waiting_new_peer_id = false;
m_indentation = 0;
m_peerhandler = peerhandler;
m_socket.Bind(0);
- // Send a dummy packet to server with peer_id = PEER_ID_NEW
- m_peer_id = PEER_ID_NEW;
+ // Send a dummy packet to server with peer_id = PEER_ID_INEXISTENT
+ m_peer_id = PEER_ID_INEXISTENT;
SharedBuffer<u8> data(0);
Send(PEER_ID_SERVER, 0, data, true);
//m_waiting_new_peer_id = true;
}
+void Connection::Disconnect()
+{
+ // Create and send DISCO packet
+ SharedBuffer<u8> data(2);
+ writeU8(&data[0], TYPE_CONTROL);
+ writeU8(&data[1], CONTROLTYPE_DISCO);
+
+ // Send to all
+ core::map<u16, Peer*>::Iterator j;
+ j = m_peers.getIterator();
+ for(; j.atEnd() == false; j++)
+ {
+ Peer *peer = j.getNode()->getValue();
+ SendAsPacket(peer->id, 0, data, false);
+ }
+}
+
bool Connection::Connected()
{
if(m_peers.size() != 1)
if(node == NULL)
return false;
- if(m_peer_id == PEER_ID_NEW)
+ if(m_peer_id == PEER_ID_INEXISTENT)
return false;
return true;
con->PrintInfo();
dout_con<<"Got new peer id: "<<peer_id_new<<"... "<<std::endl;
- if(con->GetPeerID() != PEER_ID_NEW)
+ if(con->GetPeerID() != PEER_ID_INEXISTENT)
{
con->PrintInfo(derr_con);
derr_con<<"WARNING: Not changing"
// the timeout counter
con->PrintInfo();
dout_con<<"PING"<<std::endl;
- throw ProcessedSilentlyException("Got a SET_PEER_ID");
+ throw ProcessedSilentlyException("Got a PING");
+ }
+ else if(controltype == CONTROLTYPE_DISCO)
+ {
+ // Just ignore it, the incoming data already reset
+ // the timeout counter
+ con->PrintInfo();
+ dout_con<<"DISCO: Removing peer "<<(peer_id)<<std::endl;
+
+ if(con->deletePeer(peer_id, false) == false)
+ {
+ con->PrintInfo(derr_con);
+ derr_con<<"DISCO: Peer not found"<<std::endl;
+ }
+
+ throw ProcessedSilentlyException("Got a DISCO");
}
else{
con->PrintInfo(derr_con);
throw InvalidIncomingDataException("Channel doesn't exist");
}
- if(peer_id == PEER_ID_NEW)
+ if(peer_id == PEER_ID_INEXISTENT)
{
/*
Somebody is trying to send stuff to us with no peer id.
/*
The peer was not found in our lists. Add it.
*/
- if(peer_id == PEER_ID_NEW)
+ if(peer_id == PEER_ID_INEXISTENT)
{
// Somebody wants to make a new connection
}
PrintInfo();
- dout_con<<"Receive(): Got a packet with peer_id=PEER_ID_NEW,"
+ dout_con<<"Receive(): Got a packet with peer_id=PEER_ID_INEXISTENT,"
" giving peer_id="<<peer_id_new<<std::endl;
// Create a peer
if(node == NULL)
{
// Peer not found
- // This means that the peer id of the sender is not PEER_ID_NEW
+ // This means that the peer id of the sender is not PEER_ID_INEXISTENT
// and it is invalid.
PrintInfo(derr_con);
derr_con<<"Receive(): Peer not found"<<std::endl;
continue;
}
- // Remove timeouted peers
+ // Remove timed out peers
core::list<u16>::Iterator i = timeouted_peers.begin();
for(; i != timeouted_peers.end(); i++)
{
PrintInfo(derr_con);
derr_con<<"RunTimeouts(): Removing peer "<<(*i)<<std::endl;
- m_peerhandler->deletingPeer(m_peers[*i], true);
- delete m_peers[*i];
- m_peers.remove(*i);
+ deletePeer(*i, true);
}
}
if(node == NULL){
// Peer not found
- throw PeerNotFoundException("Peer not found (possible timeout)");
+ throw PeerNotFoundException("GetPeer: Peer not found (possible timeout)");
}
// Error checking
return list;
}
+bool Connection::deletePeer(u16 peer_id, bool timeout)
+{
+ if(m_peers.find(peer_id) == NULL)
+ return false;
+ m_peerhandler->deletingPeer(m_peers[peer_id], timeout);
+ delete m_peers[peer_id];
+ m_peers.remove(peer_id);
+ return true;
+}
+
void Connection::PrintInfo(std::ostream &out)
{
out<<m_socket.GetHandle();