interreality.org [VOS]
[Home] [About]
[Screenshots]
[Download]
[News]
[Community]
[Documentation] [Manual]
[Bugs & Requests] [Wiki]

/home/tetron/hack/vos/libs/vos/vos/localsocketsite.hh

Go to the documentation of this file.
00001 #ifndef _LOCALSOCKETSITE_HH_
00002 #define _LOCALSOCKETSITE_HH_
00003 
00004 #include <stdexcept>
00005 #include <set>
00006 
00007 namespace VOS {
00008     class LocalSocketSiteExtension;
00009 }
00010 
00011 #include <vos/vos/siteextension.hh>
00012 #include <vos/vos/remotesocketsite.hh>
00013 #include <vos/vos/iterator.hh>
00014 #include <vos/vos/sitepeering.hh>
00015 
00016 #define VOS_DEFAULT_PORT 4231
00017 
00018 namespace VOS {
00019 
00020     /** @class RSSEIterator localsocketsite.hh vos/vos/localsocketsite.hh
00021         @ingroup libvos
00022 
00023         Iterator subclass used to iterate over pointers to
00024         RemoteSocketSiteExtension objects.
00025     */
00026     class VOS_API RSSEIterator : public VUtil::Iterator<RemoteSocketSiteExtension*>
00027     {
00028     public:
00029         RSSEIterator(const RSSEIterator& i) : VUtil::Iterator<RemoteSocketSiteExtension*>(i) { }
00030         RSSEIterator(const std::set<RemoteSocketSiteExtension*>& rsses) {
00031             items->resize(rsses.size());
00032             int n = 0;
00033             for(std::set<RemoteSocketSiteExtension*>::const_iterator i = rsses.begin();
00034                 i != rsses.end();
00035                 i++)
00036             {
00037                 (*items)[n] = *i;
00038                 n++;
00039             }
00040         }
00041 
00042         RemoteSocketSiteExtension* operator*() {
00043             if(pos < items->size()) return (*items)[pos];
00044             else return 0;
00045         }
00046     };
00047 
00048 
00049     /** @class LocalSocketSiteExtension localsocketsite.hh vos/vos/localsocketsite.hh
00050         @ingroup libvos
00051 
00052         This class sets up the actual socket that the VOS site will
00053         listen on and manages a list of the remote sites we are
00054         connected to.
00055     */
00056     class VOS_API LocalSocketSiteExtension : public LocalSiteExtension
00057     {
00058     private:
00059         int listensocket;
00060         unsigned short int listenport;
00061 
00062         VUtil::read_write_mutex remoteSites_mutex;
00063         std::set<RemoteSocketSiteExtension*> remoteSites;
00064 
00065         bool listener_thread_quit;
00066         boost::thread* listener_thread;
00067 
00068         void init(const std::string& defaultHostname, unsigned short int port);
00069     public:
00070         /** When creating an outgoing connection, the remote site will
00071             be peered with this local site.
00072          */
00073         static LocalSocketSiteExtension* defaultLocalSocketSite;
00074 
00075         /** Default constructor.  This will attempt to autodetect your
00076             hostname.  It will listen on the first available port it
00077             finds, starting from 4231 and working its way upward.
00078             This will use the VOS_HOSTNAME environment variable (in
00079             the form hostname:port) to define the hostname and port.
00080          */
00081         LocalSocketSiteExtension();
00082 
00083         /** Use the supplied hostname and port.
00084             @param defaultHostname the canonical hostname for this site
00085             @param port the TCP port for the site to listen on
00086             @throw PortBindingError if the port is not available.
00087          */
00088         LocalSocketSiteExtension(const std::string& defaultHostname, unsigned short int port);
00089 
00090         /** Use the supplied hostname.  Will use the first available
00091             port, starting from 4231 and working upward.
00092             @param defaultHostname the canonical hostname for this site
00093          */
00094         LocalSocketSiteExtension(const std::string& defaultHostname);
00095 
00096         /** Use the supplied port.  Will autodetect hostname, or take
00097             the canonical hostname from VOS_HOSTNAME (ignoring the
00098             port!)
00099 
00100             @param port the TCP port to listen on
00101             @throw PortBindingError if the port is not available.
00102          */
00103         LocalSocketSiteExtension(unsigned short int port);
00104 
00105         /** Destructor */
00106         virtual ~LocalSocketSiteExtension();
00107 
00108         /** @return the socket file descriptor used to accept incoming
00109             connections */
00110         int getListenSocket() { return listensocket; }
00111 
00112         /** Add a remote site that we're peered with.
00113             @param rs the RemoteSocketSiteExtension object
00114             representing the connection to the remote site
00115          */
00116         virtual void addRemoteSite(RemoteSiteExtension* rs);
00117 
00118         /** Remove a remote site that we're peered with.
00119             @param rs the RemoteSocketSiteExtension object
00120             representing the connection to the remote site
00121          */
00122         virtual void removeRemoteSite(RemoteSiteExtension* rs);
00123 
00124         /** @return the remote sites we are peered with */
00125         RSSEIterator getRemoteSites();
00126 
00127         /** Called by the Site object indicating that this extension
00128             has been attached to that site.
00129         */
00130         virtual void siteExtensionAttachedTo(Site* st);
00131     };
00132 
00133 #ifndef SWIG
00134 
00135     /** @class ListenerThread localsocketsite.hh vos/vos/localsocketsite.hh
00136         @ingroup libvos
00137 
00138         Internal thread started by LocalSocketSiteExtension.  This is
00139         the thread that actually reads incoming data from connected
00140         sockets, parses it into messages and sets them up for
00141         delivery.  It also handles output buffering and accepts
00142         incoming connections.
00143     */
00144     class VOS_API ListenerThread
00145     {
00146     private:
00147         Site* localsite;
00148         LocalSocketSiteExtension* lsse;
00149         bool* listener_thread_quit;
00150     public:
00151         /** Constructor
00152             @param ls the site we're receiving messages for
00153             @param l the local socket site extension that started this thread
00154             @param ltq a pointer to a boolean flag; when this
00155             is set to "true" the listener thread should quit
00156         */
00157         ListenerThread(Site* ls, LocalSocketSiteExtension* l, bool* ltq)
00158             : localsite(ls),
00159               lsse(l),
00160               listener_thread_quit(ltq)
00161             { };
00162 
00163         /** Entry point for thread. */
00164         void operator()();
00165     };
00166 
00167 
00168     class SocketSitePeeringThread : public SitePeeringThread
00169     {
00170     private:
00171         std::string host;
00172         int port;
00173         int newsock;
00174         sockaddr_in sockad;
00175 
00176     public:
00177 
00178         /** Construct object and initialize it so that
00179             SitePeeringThread::operator()() will use the supplied
00180             existing socket.
00181 
00182             @param l the local socket site that is the local peer
00183             @param sock the socket file descriptor
00184             @param sd the socket address of the remote site, used to
00185             do a reverse-lookup and figure out the hostname
00186             @param isClient are we a client?  default false
00187          */
00188         SocketSitePeeringThread(LocalSocketSiteExtension* l, int sock, sockaddr_in* sd,
00189                           bool isClient = false);
00190 
00191         /** Construct object and initialize it so that
00192             SitePeeringThread::operator()() will attempt an outgoing
00193             connection on the supplied host and port.
00194 
00195             @param l the local socket site that is the local peer
00196             @param host the host to connect to
00197             @param port the port to connect on
00198             @param isClient are we a client?  default true
00199          */
00200         SocketSitePeeringThread(LocalSocketSiteExtension* l, const std::string& host,
00201                           int port, bool isClient = true);
00202 
00203         /** Copy constructor, required because boost::thread makes a
00204             copy of the thread object it runs.
00205          */
00206         SocketSitePeeringThread(const SocketSitePeeringThread& spt);
00207 
00208         virtual void init();
00209         virtual void done() { }
00210     };
00211 
00212 #endif // ifndef SWIG
00213 
00214 }
00215 
00216 #endif