00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef __GNUG__
00026 # pragma implementation "SockListenModule.h"
00027 #endif
00028
00029 #include "StrMod/SockListenModule.h"
00030
00031 #ifndef _STR_SocketModule_H_
00032 # include "StrMod/SocketModule.h"
00033 #endif
00034
00035 #include <EHnet++/SocketAddress.h>
00036 #include <EHnet++/InetAddress.h>
00037
00038 #include <fcntl.h>
00039 #include <sys/types.h>
00040 #include <sys/socket.h>
00041 #include <cerrno>
00042 #include <unistd.h>
00043 #include <netinet/in.h>
00044 #include <cassert>
00045 #include <new>
00046 #include "config.h"
00047 #include "sockdecl.h"
00048 #include <iostream>
00049
00050 namespace strmod {
00051 namespace strmod {
00052
00053 using ehnet::SocketAddress;
00054 using lcore::LCoreError;
00055
00056 const STR_ClassIdent SockListenModule::identifier(13UL);
00057 const STR_ClassIdent SockListenModule::SLPlug::identifier(14UL);
00058 const STR_ClassIdent SocketModuleChunk::identifier(15UL);
00059
00060
00061
00062
00063
00064
00065
00066 class SockListenModule::FDPollEv : public unievent::Event
00067 {
00068 public:
00069 inline FDPollEv(SockListenModule &parent);
00070 virtual ~FDPollEv() { }
00071
00072 virtual void triggerEvent(Dispatcher *dispatcher = 0) = 0;
00073
00074 inline void parentGone() { hasparent_ = false; }
00075
00076 protected:
00077 inline void triggerRead();
00078 inline void triggerError();
00079
00080 private:
00081 bool hasparent_;
00082 SockListenModule &parent_;
00083 };
00084
00085 inline SockListenModule::FDPollEv::FDPollEv(SockListenModule &parent)
00086 : hasparent_(true), parent_(parent)
00087 {
00088 }
00089
00090 inline void SockListenModule::FDPollEv::triggerRead()
00091 {
00092
00093 if (hasparent_)
00094 {
00095 parent_.eventRead();
00096 }
00097 }
00098
00099 inline void SockListenModule::FDPollEv::triggerError()
00100 {
00101
00102 if (hasparent_)
00103 {
00104 parent_.eventError();
00105 }
00106 }
00107
00108
00109 class SockListenModule::FDPollRdEv : public SockListenModule::FDPollEv
00110 {
00111 public:
00112 inline FDPollRdEv(SockListenModule &parent) : FDPollEv(parent) { }
00113 virtual ~FDPollRdEv() { }
00114
00115 virtual void triggerEvent(Dispatcher *dispatcher = 0) { triggerRead(); }
00116 };
00117
00118
00119 class SockListenModule::FDPollErEv : public SockListenModule::FDPollEv {
00120 public:
00121 inline FDPollErEv(SockListenModule &parent) : FDPollEv(parent) { }
00122 virtual ~FDPollErEv() { }
00123
00124 virtual void triggerEvent(Dispatcher *dispatcher = 0) { triggerError(); }
00125 };
00126
00127 SockListenModule::SockListenModule(const SocketAddress &bind_addr,
00128 unievent::Dispatcher &disp,
00129 unievent::UnixEventRegistry &ureg,
00130 int qlen)
00131 : sockfd_(-1), has_error_(false), lplug_(*this),
00132 plug_pulled_(false), checking_read_(false), newmodule_(0),
00133 myaddr_(*(bind_addr.Copy())),
00134 disp_(disp), ureg_(ureg), readevptr_(0), errorevptr_(0)
00135 {
00136 using unievent::UNIXError;
00137 sockfd_ = socket(myaddr_.SockAddr()->sa_family, SOCK_STREAM, PF_UNSPEC);
00138 if (sockfd_ < 0)
00139 {
00140 const int myerrno = UNIXError::getErrno();
00141 setError(UNIXError("socket", myerrno,
00142 LCoreError("Creating listening socket",
00143 LCORE_GET_COMPILERINFO())));
00144 return;
00145 }
00146 {
00147 int temp = fcntl(sockfd_, F_GETFL, 0);
00148
00149 if (temp < 0)
00150 {
00151 const int myerrno = UNIXError::getErrno();
00152 setError(UNIXError("fcntl", myerrno,
00153 LCoreError("Setting non-blocking mode",
00154 LCORE_GET_COMPILERINFO())));
00155 close(sockfd_);
00156 sockfd_ = -1;
00157 return;
00158 }
00159 temp &= ~O_NDELAY;
00160 if (fcntl(sockfd_, F_SETFL, temp | O_NONBLOCK) < 0)
00161 {
00162 const int myerrno = UNIXError::getErrno();
00163 setError(UNIXError("fcntl", myerrno,
00164 LCoreError("Setting non-blocking mode",
00165 LCORE_GET_COMPILERINFO())));
00166 close(sockfd_);
00167 sockfd_ = -1;
00168 return;
00169 }
00170 }
00171 if (bind(sockfd_, myaddr_.SockAddr(), myaddr_.AddressSize()) < 0)
00172 {
00173 const int myerrno = UNIXError::getErrno();
00174
00175
00176 setError(UNIXError("bind", myerrno,
00177 LCoreError("Binding listening socket",
00178 LCORE_GET_COMPILERINFO())));
00179 close(sockfd_);
00180 sockfd_ = -1;
00181 return;
00182 }
00183 if (listen(sockfd_, qlen) < 0)
00184 {
00185 const int myerrno = UNIXError::getErrno();
00186 setError(UNIXError("listen", myerrno,
00187 LCoreError("Listening on listening socket",
00188 LCORE_GET_COMPILERINFO())));
00189 close(sockfd_);
00190 sockfd_ = -1;
00191 return;
00192 }
00193 readevptr_ = new FDPollRdEv(*this);
00194 std::cerr << "readevptr_ == " << readevptr_ << "\n";
00195 readev_ = readevptr_;
00196 errorevptr_ = new FDPollErEv(*this);
00197 std::cerr << "errorevptr_ == " << errorevptr_ << "\n";
00198 errorev_ = errorevptr_;
00199 checking_read_ = true;
00200 {
00201 static const UnixEventRegistry::FDCondSet
00202 errorconds(UnixEventRegistry::FD_Error,
00203 UnixEventRegistry::FD_Closed,
00204 UnixEventRegistry::FD_Invalid);
00205 static const UnixEventRegistry::FDCondSet
00206 readcond(UnixEventRegistry::FD_Readable);
00207 ureg_.registerFDCond(sockfd_, errorconds, errorev_);
00208 ureg_.registerFDCond(sockfd_, readcond, readev_);
00209 }
00210 }
00211
00212 SockListenModule::~SockListenModule()
00213 {
00214 if (sockfd_ >= 0)
00215 {
00216 close(sockfd_);
00217 ureg_.freeFD(sockfd_);
00218 }
00219 delete &myaddr_;
00220 if (readevptr_)
00221 {
00222 readevptr_->parentGone();
00223 }
00224 if (errorevptr_)
00225 {
00226 errorevptr_->parentGone();
00227 }
00228 }
00229
00230 void SockListenModule::eventRead()
00231 {
00232 using unievent::UNIXError;
00233 checking_read_ = false;
00234 if (newmodule_ == 0)
00235 {
00236 doAccept();
00237 }
00238 }
00239
00240 void SockListenModule::eventError()
00241 {
00242 using unievent::UNIXError;
00243 setError(UNIXError("<none>", 0,
00244 LCoreError("Got error condition",
00245 LCORE_GET_COMPILERINFO())));
00246 }
00247
00248 void SockListenModule::doAccept()
00249 {
00250 using unievent::UNIXError;
00251 assert(newmodule_ == 0);
00252
00253 if (newmodule_ != 0)
00254 {
00255 setReadableFlagFor(&lplug_, true);
00256 return;
00257 }
00258
00259 unsigned char addrbuf[8192];
00260 struct sockaddr *saddr = reinterpret_cast<struct sockaddr *>(addrbuf);
00261 size_t length = sizeof(addrbuf);
00262 #ifdef ACCEPT_NEEDS_INT
00263 int stupid_compatibility_trick = length;
00264 int tempfd = accept(sockfd_, saddr, &stupid_compatibility_trick);
00265 length = stupid_compatibility_trick;
00266 #else
00267 int tempfd = accept(sockfd_, saddr, &length);
00268 #endif
00269
00270 if (tempfd < 0)
00271 {
00272 const int myerrno = UNIXError::getErrno();
00273 if (myerrno != EAGAIN)
00274 {
00275 setError(UNIXError("accept", myerrno,
00276 LCoreError("Error accepting connection",
00277 LCORE_GET_COMPILERINFO())));
00278 }
00279 else if (!checking_read_)
00280 {
00281 static const UnixEventRegistry::FDCondSet
00282 readcond(UnixEventRegistry::FD_Readable);
00283 ureg_.registerFDCond(sockfd_, readcond, readev_);
00284 checking_read_ = true;
00285 }
00286 }
00287 else
00288 {
00289 if (saddr->sa_family != AF_INET)
00290 {
00291 close(tempfd);
00292 setError(UNIXError("<none>", 0,
00293 LCoreError("Got connection from non-AF_INET peer",
00294 LCORE_GET_COMPILERINFO())));
00295 }
00296 else
00297 {
00298 {
00299 int temp = fcntl(tempfd, F_GETFL, 0);
00300
00301 if (temp < 0)
00302 {
00303 const int myerrno = UNIXError::getErrno();
00304 setError(UNIXError("fcntl", myerrno,
00305 LCoreError("Setting accepted connection non-blocking",
00306 LCORE_GET_COMPILERINFO())));
00307 close(tempfd);
00308 tempfd = -1;
00309 }
00310 else
00311 {
00312 temp &= ~O_NDELAY;
00313 if (fcntl(tempfd, F_SETFL, temp | O_NONBLOCK) < 0)
00314 {
00315 const int myerrno = UNIXError::getErrno();
00316 setError(UNIXError("fcntl", myerrno,
00317 LCoreError("Setting accepted connection non-blocking",
00318 LCORE_GET_COMPILERINFO())));
00319 close(tempfd);
00320 tempfd = -1;
00321 return;
00322 }
00323 }
00324 }
00325
00326 if (tempfd >= 0)
00327 {
00328 sockaddr_in *sinad
00329 = reinterpret_cast<struct sockaddr_in *>(saddr);
00330 ehnet::InetAddress *addr = new ehnet::InetAddress(*sinad);
00331
00332 newmodule_ = makeSocketModule(tempfd, addr, disp_, ureg_);
00333 }
00334 }
00335 }
00336 if (newmodule_ != 0)
00337 {
00338 setReadableFlagFor(&lplug_, true);
00339 }
00340 else
00341 {
00342 setReadableFlagFor(&lplug_, false);
00343 }
00344 }
00345
00346 void SockListenModule::clearError() throw()
00347 {
00348 using unievent::UNIXError;
00349 if (has_error_)
00350 {
00351 (reinterpret_cast<UNIXError *>(errorstore_))->~UNIXError();
00352 has_error_ = false;
00353 }
00354 }
00355
00356 const unievent::UNIXError &SockListenModule::getError() const throw()
00357 {
00358 using unievent::UNIXError;
00359 const void *raw = errorstore_;
00360 return *reinterpret_cast<const UNIXError *>(raw);
00361 }
00362
00363 void SockListenModule::setError(const unievent::UNIXError &err) throw()
00364 {
00365 using unievent::UNIXError;
00366 void *raw = errorstore_;
00367 UNIXError *store = reinterpret_cast<UNIXError *>(raw);
00368 if (has_error_)
00369 {
00370 store->~UNIXError();
00371 }
00372 else
00373 {
00374 has_error_ = true;
00375 }
00376 new(raw) UNIXError(err);
00377 }
00378
00379 SocketModule *SockListenModule::getNewModule()
00380 {
00381 SocketModule *retval = newmodule_;
00382
00383 if (newmodule_ != 0)
00384 {
00385 newmodule_ = 0;
00386 doAccept();
00387 }
00388 return(retval);
00389 }
00390
00391 const SocketModuleChunkPtr SockListenModule::SLPlug::getConnection()
00392 {
00393 return(new SocketModuleChunk(getParent().getNewModule()));
00394 }
00395
00396 const StrChunkPtr SockListenModule::SLPlug::i_Read()
00397 {
00398 return(getConnection());
00399 }
00400
00401 void SockListenModule::SLPlug::i_Write(const StrChunkPtr &chunk)
00402 {
00403 assert(false);
00404 }
00405
00406 };
00407 };