1 #include "../../include/nntp/nntplistener.h"
\r
2 #include "../../include/nntp/nntpconnection.h"
\r
3 #include "../../include/option.h"
\r
4 #include "../../include/global.h"
\r
5 #include "../../include/stringfunctions.h"
\r
7 #include <Poco/Net/SocketAddress.h>
\r
12 #include <winsock2.h>
\r
13 #include <ws2tcpip.h>
\r
15 #include <netinet/in.h> // gcc - IPPROTO_ consts
\r
16 #include <netdb.h> // gcc - addrinfo
\r
23 NNTPListener::NNTPListener()
\r
28 NNTPListener::~NNTPListener()
\r
33 void NNTPListener::run()
\r
38 std::vector<SOCKET>::iterator listeni;
\r
41 m_log->debug("NNTPListener::run thread started.");
\r
57 // put all listen sockets on the fd set
\r
58 for(listeni=m_listensockets.begin(); listeni!=m_listensockets.end(); listeni++)
\r
60 FD_SET((*listeni),&readfs);
\r
61 if((*listeni)>highsocket)
\r
63 highsocket=(*listeni);
\r
67 // see if any connections are waiting
\r
68 rval=select(highsocket+1,&readfs,0,0,&tv);
\r
70 // check for new connections
\r
73 for(listeni=m_listensockets.begin(); listeni!=m_listensockets.end(); listeni++)
\r
75 if(FD_ISSET((*listeni),&readfs))
\r
78 struct sockaddr_storage addr;
\r
79 socklen_t addrlen=sizeof(addr);
\r
80 newsock=accept((*listeni),(struct sockaddr *)&addr,&addrlen);
\r
81 m_log->information("NNTPListener::run NNTP client connected");
\r
82 m_connections.Start(new NNTPConnection(newsock));
\r
87 }while(!IsCancelled() && m_listensockets.size()>0);
\r
89 m_connections.Cancel();
\r
90 m_connections.Join();
\r
92 for(listeni=m_listensockets.begin(); listeni!=m_listensockets.end(); listeni++)
\r
95 closesocket((*listeni));
\r
100 m_listensockets.clear();
\r
102 m_log->debug("NNTPListener::run thread exiting.");
\r
106 void NNTPListener::StartListen()
\r
109 std::vector<std::string> listenaddresses;
\r
110 std::string bindaddresses;
\r
111 std::string nntpport;
\r
112 Option option(m_db);
\r
114 if(option.Get("NNTPListenPort",nntpport)==false)
\r
117 option.Set("NNTPListenPort",nntpport);
\r
119 if(option.Get("NNTPBindAddresses",bindaddresses)==false)
\r
121 bindaddresses="127.0.0.1";
\r
122 option.Set("NNTPBindAddresses",bindaddresses);
\r
125 StringFunctions::Split(bindaddresses,",",listenaddresses);
\r
127 for(std::vector<std::string>::iterator i=listenaddresses.begin(); i!=listenaddresses.end(); i++)
\r
131 struct addrinfo hint,*result,*current;
\r
132 result=current=NULL;
\r
133 memset(&hint,0,sizeof(hint));
\r
134 hint.ai_socktype=SOCK_STREAM;
\r
135 hint.ai_protocol=IPPROTO_TCP;
\r
136 hint.ai_flags=AI_PASSIVE;
\r
138 m_log->trace("NNTPListener::StartListen getting address info for "+(*i));
\r
140 rval=getaddrinfo((*i).c_str(),nntpport.c_str(),&hint,&result);
\r
143 for(current=result; current!=NULL; current=current->ai_next)
\r
147 Poco::Net::SocketAddress sa(current->ai_addr,current->ai_addrlen);
\r
149 m_log->debug("NNTPListener::StartListen trying to create socket, bind, and listen on "+sa.toString());
\r
151 sock=socket(current->ai_family,current->ai_socktype,current->ai_protocol);
\r
152 if(sock!=INVALID_SOCKET)
\r
155 const char optval='1';
\r
156 setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));
\r
158 if(bind(sock,current->ai_addr,current->ai_addrlen)==0)
\r
160 if(listen(sock,10)==0)
\r
162 m_log->information("NNTPListener::StartListen started listening on "+sa.toString());
\r
163 m_listensockets.push_back(sock);
\r
167 m_log->error("NNTPListener::StartListen socket listen failed on "+sa.toString());
\r
177 m_log->error("NNTPListener::StartListen socket bind failed on "+sa.toString());
\r
187 m_log->error("NNTPListener::StartListen couldn't create socket on "+sa.toString());
\r
190 catch(Poco::Exception &e)
\r
192 m_log->error("NNTPListener::StartListen caught "+e.displayText());
\r
197 m_log->error("NNTPListener::StartListen caught unknown exception");
\r
204 freeaddrinfo(result);
\r
207 if(m_listensockets.size()==0)
\r
209 m_log->fatal("NNTPListener::StartListen couldn't start listening on any interfaces");
\r