1 /* Copyright (C) 2005 RealVNC Ltd.  All Rights Reserved.
2  *
3  * This is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This software is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this software; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
16  * USA.
17  */
18 #include <winvnc/ManagedListener.h>
19 #include <rfb/LogWriter.h>
20 
21 using namespace winvnc;
22 using namespace rfb;
23 using namespace win32;
24 
25 static LogWriter vlog("ManagedListener");
26 
27 
ManagedListener(SocketManager * mgr)28 ManagedListener::ManagedListener(SocketManager* mgr)
29 : filter(0), manager(mgr), addrChangeNotifier(0), server(0), port(0), localOnly(false) {
30 }
31 
~ManagedListener()32 ManagedListener::~ManagedListener() {
33   if (!sockets.empty()) {
34     std::list<network::SocketListener*>::iterator iter;
35     for (iter = sockets.begin(); iter != sockets.end(); ++iter)
36       manager->remListener(*iter);
37     sockets.clear();
38   }
39   delete filter;
40 }
41 
42 
setServer(network::SocketServer * svr)43 void ManagedListener::setServer(network::SocketServer* svr) {
44   if (svr == server)
45     return;
46   vlog.info("set server to %p", svr);
47   server = svr;
48   refresh();
49 }
50 
setPort(int port_,bool localOnly_)51 void ManagedListener::setPort(int port_, bool localOnly_) {
52   if ((port_ == port) && (localOnly == localOnly_))
53     return;
54   vlog.info("set port to %d", port_);
55   port = port_;
56   localOnly = localOnly_;
57   refresh();
58 }
59 
setFilter(const char * filterStr)60 void ManagedListener::setFilter(const char* filterStr) {
61   vlog.info("set filter to %s", filterStr);
62   delete filter;
63   filter = new network::TcpFilter(filterStr);
64   if (!sockets.empty() && !localOnly) {
65     std::list<network::SocketListener*>::iterator iter;
66     for (iter = sockets.begin(); iter != sockets.end(); ++iter)
67       (*iter)->setFilter(filter);
68   }
69 }
70 
setAddressChangeNotifier(SocketManager::AddressChangeNotifier * acn)71 void ManagedListener::setAddressChangeNotifier(SocketManager::AddressChangeNotifier* acn) {
72   if (acn == addrChangeNotifier)
73     return;
74   addrChangeNotifier = acn;
75   refresh();
76 }
77 
isListening()78 bool ManagedListener::isListening() {
79   return !sockets.empty();
80 }
81 
refresh()82 void ManagedListener::refresh() {
83   std::list<network::SocketListener*>::iterator iter;
84   if (!sockets.empty()) {
85     for (iter = sockets.begin(); iter != sockets.end(); ++iter)
86       manager->remListener(*iter);
87     sockets.clear();
88   }
89   if (!server)
90     return;
91   try {
92     if (port) {
93       if (localOnly)
94         network::createLocalTcpListeners(&sockets, port);
95       else
96         network::createTcpListeners(&sockets, NULL, port);
97     }
98   } catch (rdr::Exception& e) {
99     vlog.error("%s", e.str());
100   }
101   if (!sockets.empty()) {
102     if (!localOnly) {
103       for (iter = sockets.begin(); iter != sockets.end(); ++iter)
104         (*iter)->setFilter(filter);
105     }
106     try {
107       for (iter = sockets.begin(); iter != sockets.end(); ++iter)
108         manager->addListener(*iter, server, addrChangeNotifier);
109     } catch (...) {
110       std::list<network::SocketListener*>::iterator iter2;
111       for (iter2 = sockets.begin(); iter2 != iter; ++iter2)
112         manager->remListener(*iter2);
113       for (; iter2 != sockets.end(); ++iter2)
114         delete *iter;
115       sockets.clear();
116       throw;
117     }
118   }
119 }
120