X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=blobdiff_plain;f=src%2Fconnection.cpp;h=687906708806630e59ddd8dca8e5045208a8e5fe;hp=b4cf198abc9fe514af6bb06c831b1c934b47a8a9;hb=a63e08b83794273da3840e0b8bf15bf0085fe3c4;hpb=a64066eb0e456c92c4c06959616443e531d4b39d diff --git a/src/connection.cpp b/src/connection.cpp index b4cf198..6879067 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -1,25 +1,29 @@ -/*************************************************************************** - * Copyright (C) 2006 by Gerd v. Egidy * - * gve@intra2net.com * - * * - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License version * - * 2.1 as published by the Free Software Foundation. * - * * - * This library 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 Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ +/* +Copyright (C) 2006 by Intra2net AG - Gerd v. Egidy + +The software in this package is distributed under the GNU General +Public License version 2 (with a special exception described below). + +A copy of GNU General Public License (GPL) is included in this distribution, +in the file COPYING.GPL. + +As a special exception, if other files instantiate templates or use macros +or inline functions from this file, or you compile this file and link it +with other works to produce a work based on this file, this file +does not by itself cause the resulting work to be covered +by the GNU General Public License. + +However the source code for this file must still be made available +in accordance with section (3) of the GNU General Public License. + +This exception does not invalidate any other reasons why a work based +on this file might be covered by the GNU General Public License. +*/ #include #include #include +#include #include @@ -30,8 +34,13 @@ namespace libt2n connection::~connection() { - // we want the connection_closed callbacks to be called before - close(); + // Run close() manually since it's a virtual function + // and we are in the destructor. + if (!is_closed()) + { + closed=true; + do_callbacks(connection_closed); + } do_callbacks(connection_deleted); } @@ -45,6 +54,7 @@ void connection::close() } } +/// get the number of bytes being available as next complete packet connection::packet_size_indicator connection::bytes_available() { // no size information -> no packet @@ -103,6 +113,39 @@ unsigned int connection::peek_packet(std::string& data) return psize; } +/// remove all data from buffer that is not a complete packet +void connection::remove_incomplete_packets() +{ + std::string::size_type p=0; + std::string::size_type end=buffer.size(); + + while (p < end) + { + // not enough space for size information -> no packet + if (p+sizeof(packet_size_indicator) > end) + break; + + packet_size_indicator psize=ntohl(*((packet_size_indicator*)(buffer.data()+p))); + + if (p+sizeof(packet_size_indicator)+psize > end) + { + // incomplete packet + break; + } + else + { + // move p to where the next packet will start + p+=sizeof(packet_size_indicator)+psize; + } + } + + if (p < end) + { + // incomplete packets there, remove them + buffer.erase(p); + } +} + /// send a blob to the peer void connection::write(const std::string& data) { @@ -125,15 +168,12 @@ void connection::write(const std::string& data) */ void connection::add_callback(callback_event_type event, const boost::function& func) { - if (event == new_connection) - throw std::logic_error("new_connection callback not allowed for server_connections"); - callbacks[event].push_back(func); } -/** @brief an event has occured, execute the callbacks that are registered for this event +/** @brief an event has occurred, execute the callbacks that are registered for this event - @param event event type that has occured + @param event event type that has occurred */ void connection::do_callbacks(callback_event_type event) { @@ -154,5 +194,24 @@ std::list > connection::get_callback_list(callback_even return callbacks[event]; } +/** @brief reopen a already closed connection, removes incomplete packets from the buffer + + @note Only call when the connection is closed. + + @note Justs cares about the data of connection, reconnecting has to be + done in a derived class. +*/ +void connection::reopen() +{ + if (!is_closed()) + throw std::logic_error("connection::reopen() called with connection still open"); + + closed=false; + + // incomplete buffer data is worthless with a new connection + remove_incomplete_packets(); + + do_callbacks(new_connection); +} }