/* doscan - Denial Of Service Capable Auditing of Networks -*- C++ -*- * Copyright (C) 2003 Florian Weimer * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef HALF_DUPLEX_H #define HALF_DUPLEX_H #include "event_queue.h" #include class half_duplex_handler : public event_queue::fd_handler { // Override routines inherited from fd_handler. virtual bool on_timeout(ticks_t); virtual bool on_activity(activity); bool on_activity_read(); bool on_activity_write(); bool invoke_ready(); int get_error(); protected: int state; std::string receive_buffer; std::string send_buffer; private: std::string::size_type receive_goal; std::string::size_type send_offset; // invoke_ready() sets this variable to true before calling ready(), // and the requested*() and send() members set it to false. Thus we // can check if a new operation has been requested. bool stop; public: // Handles an existing half-duplex connection. // // If first_read is true, the first operation is a read operation, // otherwise it's a write operation. half_duplex_handler(event_queue&, int fd, bool first_read); // Automatically closes the file descriptor. virtual ~half_duplex_handler(); // ready() is called when the requested amount of data has been // received, or a send operation has completed and some data has // been received. // // The first state is 0. Its value is special and the state should // not be entered again. virtual void ready() = 0; // This is called when an error is detected, or the peer closes the // connection. The argument is the errno number, or 0 if the // connection has just been closed. virtual void error(int) = 0; // request_data() should be called by ready() to request more data. // If count bytes are received, ready() is invoked again, with the // given state. (If count is zero, all the data in the socket // buffer is read.) void request_data(unsigned count = 0); // request_more_data() is like request_data(), only the data is // appended to the existing buffer. void request_more_data(unsigned count = 0); // send() should be called by ready() to send the data in // send_buffer. After completion, ready() is invoked with the new // state. void send(); // Line send(), but assigns the argument to send_buffer. void send(const std::string&); }; inline void half_duplex_handler::request_more_data(unsigned count) { receive_goal = count; watch(watch_read); stop = false; } inline void half_duplex_handler::send() { send_offset = 0; watch(watch_write); stop = false; } inline void half_duplex_handler::send(const std::string& data) { send_buffer.assign(data); send(); } inline bool half_duplex_handler::invoke_ready() { stop = true; ready(); return !stop; } #endif // HALF_DUPLEX_H // arch-tag: df1a7c50-42d8-4cb8-9a82-c3c29608a292