bool SocketUtil::isSelfConnect(ZL_SOCKET sockfd) { struct sockaddr_in localaddr = getLocalAddr(sockfd); struct sockaddr_in peeraddr = getPeerAddr(sockfd); return localaddr.sin_port == peeraddr.sin_port && localaddr.sin_addr.s_addr == peeraddr.sin_addr.s_addr; }
bool Socket::onOutput(StreamBuffer& sb) { log_trace("onOutput"); log_debug("send data to " << getPeerAddr()); try { sb.endWrite(); if ( sb.out_avail() ) { sb.beginWrite(); } else { if (sb.in_avail()) onInput(sb); else sb.beginRead(); } } catch (const std::exception& e) { log_warn("exception occured when processing request: " << e.what()); close(); return false; } return true; }
bool isSelfConnect(int sockfd) { struct sockaddr_in localaddr = getLocalAddr(sockfd); struct sockaddr_in peeraddr = getPeerAddr(sockfd); return localaddr.sin_port == peeraddr.sin_port && localaddr.sin_addr.s_addr == peeraddr.sin_addr.s_addr; }
static void defaultAfterAccept(struct BufferEvent* bevent, void* arg) { assert(bevent != NULL); int connfd = bevent->event->fd; char local[25]; char peer[25]; printf("%s -> %s.\n", getPeerAddr(connfd, peer, sizeof(peer)), getLocalAddr(connfd, local, sizeof(local))); }
bool Socket::onOutput(StreamBuffer& sb) { log_trace("onOutput"); log_debug("send data to " << getPeerAddr()); try { sb.endWrite(); if ( sb.out_avail() ) { sb.beginWrite(); _timer.start(_server.writeTimeout()); } else { bool keepAlive = _request.header().keepAlive() && _reply.header().keepAlive(); if (keepAlive) { log_debug("do keep alive"); _timer.start(_server.keepAliveTimeout()); _request.clear(); _reply.clear(); _parser.reset(false); if (sb.in_avail()) onInput(sb); else _stream.buffer().beginRead(); } else { log_debug("don't do keep alive"); close(); return false; } } } catch (const std::exception& e) { log_warn("exception occured when processing request: " << e.what()); close(); timeout(*this); return false; } return true; }
void TcpSocketImpl::accept(const TcpServer& server, unsigned flags) { socklen_t peeraddr_len = sizeof(_peeraddr); _fd = server.impl().accept(flags, reinterpret_cast <struct sockaddr*>(&_peeraddr), peeraddr_len); if( _fd < 0 ) throw SystemError("accept"); #ifdef HAVE_ACCEPT4 IODeviceImpl::open(_fd, false, false); #else bool inherit = (flags & TcpSocket::INHERIT) != 0; IODeviceImpl::open(_fd, true, inherit); #endif //TODO ECONNABORTED EINTR EPERM _isConnected = true; log_debug( "accepted from " << getPeerAddr()); }
int TcpSocketImpl::checkConnect() { log_trace("checkConnect"); int sockerr; socklen_t optlen = sizeof(sockerr); // check for socket error if( ::getsockopt(this->fd(), SOL_SOCKET, SO_ERROR, &sockerr, &optlen) != 0 ) { // getsockopt failed int e = errno; close(); throw SystemError(e, "getsockopt"); } if (sockerr == 0) { log_debug("connected successfully to " << getPeerAddr()); _isConnected = true; } return sockerr; }
std::string TcpSocketImpl::tryConnect() { log_trace("tryConnect"); assert(_fd == -1); if (_addrInfoPtr == _addrInfo.impl()->end()) { log_debug("no more address informations"); std::ostringstream msg; msg << "invalid address information; host \"" << _addrInfo.host() << "\" port " << _addrInfo.port(); return msg.str(); } while (true) { int fd; while (true) { log_debug("create socket"); fd = ::socket(_addrInfoPtr->ai_family, SOCK_STREAM, 0); if (fd >= 0) break; if (++_addrInfoPtr == _addrInfo.impl()->end()) { std::ostringstream msg; msg << "failed to create socket for host \"" << _addrInfo.host() << "\" port " << _addrInfo.port() << ": " << getErrnoString(); return msg.str(); } } #ifdef HAVE_SO_NOSIGPIPE static const int on = 1; if (::setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)) < 0) throw cxxtools::SystemError("setsockopt(SO_NOSIGPIPE)"); #endif IODeviceImpl::open(fd, true, false); std::memmove(&_peeraddr, _addrInfoPtr->ai_addr, _addrInfoPtr->ai_addrlen); log_debug("created socket " << _fd << " max: " << FD_SETSIZE); if( ::connect(this->fd(), _addrInfoPtr->ai_addr, _addrInfoPtr->ai_addrlen) == 0 ) { _isConnected = true; log_debug("connected successfully to " << getPeerAddr()); break; } if (errno == EINPROGRESS) { log_debug("connect in progress"); break; } close(); if (++_addrInfoPtr == _addrInfo.impl()->end()) return connectFailedMessage(_addrInfo, errno); } return std::string(); }
void Socket::onInput(StreamBuffer& sb) { log_debug("onInput"); sb.endRead(); if (sb.in_avail() == 0 || sb.device()->eof()) { close(); return; } _timer.start(_server.readTimeout()); if ( _responder == 0 ) { _parser.advance(sb); if (_parser.fail()) { _responder = _server.getDefaultResponder(_request); _responder->replyError(_reply.body(), _request, _reply, std::runtime_error("invalid http header")); _responder->release(); _responder = 0; sendReply(); onOutput(sb); return; } if (_parser.end()) { log_info("request " << _request.method() << ' ' << _request.header().query() << " from client " << getPeerAddr()); _responder = _server.getResponder(_request); try { _responder->beginRequest(_stream, _request); } catch (const std::exception& e) { _reply.setHeader("Connection", "close"); _responder->replyError(_reply.body(), _request, _reply, e); _responder->release(); _responder = 0; sendReply(); onOutput(sb); return; } _contentLength = _request.header().contentLength(); log_debug("content length of request is " << _contentLength); if (_contentLength == 0) { _timer.stop(); doReply(); return; } } else { sb.beginRead(); } } if (_responder) { if (sb.in_avail() > 0) { try { std::size_t s = _responder->readBody(_stream); assert(s > 0); _contentLength -= s; } catch (const std::exception& e) { _reply.setHeader("Connection", "close"); _responder->replyError(_reply.body(), _request, _reply, e); _responder->release(); _responder = 0; sendReply(); onOutput(sb); return; } } if (_contentLength <= 0) { _timer.stop(); doReply(); } else { sb.beginRead(); } } }