xorp

socket.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2009 XORP, Inc.
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, Version 2, June
00007 // 1991 as published by the Free Software Foundation. Redistribution
00008 // and/or modification of this program under the terms of any other
00009 // version of the GNU General Public License is not permitted.
00010 // 
00011 // This program is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00014 // see the GNU General Public License, Version 2, a copy of which can be
00015 // found in the XORP LICENSE.gpl file.
00016 // 
00017 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00018 // http://xorp.net
00019 
00020 // $XORP: xorp/bgp/socket.hh,v 1.24 2008/10/02 21:56:21 bms Exp $
00021 
00022 #ifndef __BGP_SOCKET_HH__
00023 #define __BGP_SOCKET_HH__
00024 
00025 // #define DEBUG_PEERNAME
00026 
00027 #include "libxorp/xorp.h"
00028 #include "libxorp/debug.h"
00029 #include "libxorp/exceptions.hh"
00030 #include "libxorp/xorpfd.hh"
00031 #include "libxorp/eventloop.hh"
00032 #include "libxorp/asyncio.hh"
00033 #include "libxorp/callback.hh"
00034 
00035 #ifdef HAVE_NETDB_H
00036 #include <netdb.h>
00037 #endif
00038 
00039 #ifdef HAVE_SYS_SOCKET_H
00040 #include <sys/socket.h>
00041 #endif
00042 #ifdef HAVE_SYS_UN_H
00043 #include <sys/un.h>
00044 #endif
00045 
00046 #ifdef HAVE_NETINET_IN_H
00047 #include <netinet/in.h>
00048 #endif
00049 
00050 #include "packet.hh"
00051 #include "iptuple.hh"
00052 
00053 
00054 /* **************** BGPSocket *********************** */
00055 
00056 class Socket {
00057 public:
00058     static const int MAX_LISTEN_QUEUE = 5;
00059 
00060     Socket(const Iptuple& iptuple, EventLoop& e);
00061 
00070     static void init_sockaddr(string addr, uint16_t local_port,
00071                   struct sockaddr_storage& ss, size_t& len);
00072 
00073     //    void set_eventloop(EventLoop *evt) {_eventloop = evt;}
00074     EventLoop& eventloop() {return _eventloop;}
00075 
00076     XorpFd get_sock() { return _s; }
00077 
00078     void create_listener();
00079 
00080     /* Intended for debugging use only */
00081     void set_remote_host(const char *s) {_remote_host = s;}
00082     const char  *get_remote_host() {return _remote_host.c_str();}
00083 
00084 protected:
00085     void set_sock(XorpFd s) { _s = s; }
00086 
00087     void close_socket();
00088     void create_socket(const struct sockaddr *sin, int is_blocking);
00089 
00090     const struct sockaddr *get_local_socket(size_t& len) {
00091     return _iptuple.get_local_socket(len);
00092     }
00093     const string& get_local_interface() const { return _iptuple.get_local_interface(); }
00094     string get_local_addr() {return _iptuple.get_local_addr();}
00095     uint16_t get_local_port() {return _iptuple.get_local_port();}
00096 
00097     const struct sockaddr *get_bind_socket(size_t& len) {
00098     return _iptuple.get_bind_socket(len);
00099     }
00100 
00101     const struct sockaddr *get_remote_socket(size_t& len) {
00102     return _iptuple.get_peer_socket(len);
00103     }
00104     string get_remote_addr() {return _iptuple.get_peer_addr();}
00105     uint16_t get_remote_port() {return _iptuple.get_peer_port();}
00106 private:
00107     XorpFd _s;
00108 
00109     /*
00110     ** All in network byte order.
00111     */
00112     const Iptuple _iptuple;
00113 
00114     EventLoop& _eventloop;
00115 
00116     /*
00117     ** Remote host. For debugging only
00118     */
00119     string _remote_host;
00120 };
00121 
00122 class SocketClient : public Socket {
00123 public:
00127     SocketClient(const Iptuple& iptuple, EventLoop& e, bool md5sig = false);
00128     ~SocketClient();
00129 
00133     typedef XorpCallback1<void, bool>::RefPtr ConnectCallback;
00134 
00140     void connect(ConnectCallback cb);
00141 
00150     void connect_break();
00151 
00157     void connected(XorpFd s);
00158 
00162     void flush_transmit_queue();
00163 
00167     void stop_reader() {async_remove_reader();}
00168 
00172     void disconnect();
00173 
00177     bool disconnecting() {return _disconnecting;}
00178 
00185     typedef XorpCallback4<bool,BGPPacket::Status,const uint8_t*,size_t,
00186               SocketClient*>::RefPtr MessageCallback;
00187 
00191     void set_callback(const MessageCallback& cb) {_callback = cb;}
00192 
00193     enum Event {
00194     DATA = AsyncFileWriter::DATA,
00195     FLUSHING = AsyncFileWriter::FLUSHING,
00196     ERROR = AsyncFileWriter::OS_ERROR
00197     };
00198 
00206     typedef XorpCallback2<void,Event,const uint8_t*>::RefPtr
00207     SendCompleteCallback;
00208                   
00219     bool send_message(const uint8_t* buf,
00220               size_t cnt, 
00221               SendCompleteCallback cb);
00222 
00232     bool output_queue_busy() const;
00233 
00237     int output_queue_size() const;
00238 
00242     bool is_connected();
00243 
00247     bool still_reading();
00248 protected:
00249 private:
00250     void connect_socket(XorpFd sock, string raddr, uint16_t port,
00251             string laddr, ConnectCallback cb);
00252     void connect_socket_complete(XorpFd fd, IoEventType type,
00253                  ConnectCallback cb);
00254     void connect_socket_break();
00255 
00256     void async_add(XorpFd sock);
00257     void async_remove();
00258     void async_remove_reader();
00259     
00260     void read_from_server(XorpFd sock);
00261     void write_to_server(XorpFd sock);
00262 
00263     void send_message_complete(AsyncFileWriter::Event e,
00264                   const uint8_t* buf,
00265                   const size_t buf_bytes,
00266                   const size_t offset,
00267                   SendCompleteCallback cb);
00268 
00269     void async_read_start(size_t cnt = BGPPacket::COMMON_HEADER_LEN,
00270               size_t ofset = 0);
00271     void async_read_message(AsyncFileWriter::Event ev,
00272                const uint8_t *buf,
00273                const size_t buf_bytes,
00274                const size_t offset);
00275 
00276     MessageCallback _callback;
00277     AsyncFileWriter *_async_writer;
00278     AsyncFileReader *_async_reader;
00279 
00280     bool _disconnecting;
00281     bool _connecting;
00282     bool _md5sig;
00283 
00284     uint8_t _read_buf[BGPPacket::MAXPACKETSIZE]; // Maximum allowed BGP message
00285 };
00286 
00287 class SocketServer : public Socket {
00288 public:
00289     SocketServer(EventLoop& e);
00290     SocketServer(const Iptuple& iptuple, EventLoop& e);
00291 };
00292 
00293 #endif // __BGP_SOCKET_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations