/* Accept a connection. Called as a callback on incoming connection. */ static void socketAccept(WebsSocket *sp) { struct sockaddr_storage addrStorage; struct sockaddr *addr; WebsSocket *nsp; Socket newSock; size_t len; char ipbuf[1024]; int port, nid; assert(sp); /* Accept the connection and prevent inheriting by children (F_SETFD) */ len = sizeof(addrStorage); addr = (struct sockaddr*) &addrStorage; if ((newSock = accept(sp->sock, addr, (Socklen*) &len)) == SOCKET_ERROR) { return; } #if ME_COMPILER_HAS_FCNTL fcntl(newSock, F_SETFD, FD_CLOEXEC); #endif socketHighestFd = max(socketHighestFd, newSock); /* Create a socket structure and insert into the socket list */ nid = socketAlloc(sp->ip, sp->port, sp->accept, sp->flags); if ((nsp = socketList[nid]) == 0) { return; } assert(nsp); nsp->sock = newSock; nsp->flags &= ~SOCKET_LISTENING; socketSetBlock(nid, (nsp->flags & SOCKET_BLOCK)); if (nsp->flags & SOCKET_NODELAY) { socketSetNoDelay(nid, 1); } /* Call the user accept callback. The user must call socketCreateHandler to register for further events of interest. */ if (sp->accept != NULL) { /* Get the remote client address */ socketAddress(addr, (int) len, ipbuf, sizeof(ipbuf), &port); if ((sp->accept)(nid, ipbuf, port, sp->sid) < 0) { socketFree(nid); } } }
HttpSocket::HttpSocket(const QString &iface, quint16 port) : QTcpServer(nullptr) , cfgInterface(iface) , terminated(false) { if (!openPort(port)) { openPort(0); } DBUG << isListening() << serverPort(); connect(MPDConnection::self(), SIGNAL(socketAddress(QString)), this, SLOT(mpdAddress(QString))); connect(MPDConnection::self(), SIGNAL(cantataStreams(QList<Song>,bool)), this, SLOT(cantataStreams(QList<Song>,bool))); connect(MPDConnection::self(), SIGNAL(cantataStreams(QStringList)), this, SLOT(cantataStreams(QStringList))); connect(MPDConnection::self(), SIGNAL(removedIds(QSet<qint32>)), this, SLOT(removedIds(QSet<qint32>))); connect(this, SIGNAL(newConnection()), SLOT(handleNewConnection())); }
void Client::threadedFunction() { while (isThreadRunning()) { Poco::Net::SocketAddress socketAddress(_settings.getHost(), _settings.getPort()); SharedSocket pSocket; try { if (Settings::SSLTLS == _settings.getEncryptionType()) { // Create a Poco::Net::SecureStreamSocket pointer. Poco::Net::SecureStreamSocket* _socket = 0; // We get a default context from ofSSLManager to make sure // that Poco::Net::SecureStreamSocket doesn't attempt to create // a default context using Poco::Net::SSLManager. Poco::Net::Context::Ptr _clientContext = ofSSLManager::getDefaultClientContext(); // Create a Poco::Net::SecureStreamSocket and connect to it. // Use the Default Client context from ofSSLManager and // attempt to use saved Poco::Nett::Session on subsequent // attempts the Client SSL Context and server allow it, // and one was saved during a previous connection. _socket = new Poco::Net::SecureStreamSocket(socketAddress, _clientContext, _pSession); // Attempt to save an SSL Client session. _pSession = _socket->currentSession(); // Let the shared pointer take ownership of the raw pointer. pSocket = SharedSocket(_socket); } else { pSocket = SharedSocket(new Poco::Net::StreamSocket(socketAddress)); } #if defined(TARGET_OSX) // essential on early versions of Poco! fixed in 1.4.6p2+ / 1.5.2+ // https://github.com/pocoproject/poco/issues/235 pSocket->setOption(SOL_SOCKET, SO_NOSIGPIPE, 1); // ignore SIGPIPE #endif Poco::Net::SecureSMTPClientSession session(*pSocket); session.setTimeout(_settings.getTimeout()); if (Settings::STARTTLS == _settings.getEncryptionType()) { // Make the initial connection. session.login(); // TODO: // This is supposed to return true on succes, but it doesn't. session.startTLS(ofSSLManager::getDefaultClientContext()); } if (_settings.getCredentials().getLoginMethod() != Poco::Net::SMTPClientSession::AUTH_NONE) { session.login(_settings.getCredentials().getLoginMethod(), _settings.getCredentials().getUsername(), _settings.getCredentials().getPassword()); } while (getOutboxSize() > 0 && isThreadRunning()) { mutex.lock(); _currentMessage = _outbox.front(); _outbox.pop_front(); mutex.unlock(); session.sendMessage(*_currentMessage); ofNotifyEvent(events.onSMTPDelivery, _currentMessage, this); _currentMessage.reset(); sleep(_settings.getMessageSendDelay().milliseconds()); } ofLogVerbose("Client::threadedFunction") << "Closing session."; session.close(); pSocket->close(); } catch (Poco::Net::SMTPException& exc) { if (_currentMessage) { // 500 codes are permanent negative errors. if (5 != (exc.code() / 100)) { mutex.lock(); _outbox.push_front(_currentMessage); mutex.unlock(); } } pSocket->close(); ErrorArgs args(exc, _currentMessage); ofNotifyEvent(events.onSMTPException, args, this); _currentMessage.reset(); } catch (Poco::Net::SSLException& exc) { if (_currentMessage) { mutex.lock(); _outbox.push_front(_currentMessage); mutex.unlock(); } ofLogError("Client::threadedFunction") << exc.name() << " : " << exc.displayText(); if (exc.displayText().find("SSL3_GET_SERVER_CERTIFICATE") != string::npos) { ofLogError("Client::threadedFunction") << "\t\t" << "This may be because you asked your SSL context to verify the server's certificate, but your certificate authority (ca) file is missing."; } ErrorArgs args(exc, _currentMessage); ofNotifyEvent(events.onSMTPException, args, this); _currentMessage.reset(); } catch (Poco::Net::NetException& exc) { if (_currentMessage) { mutex.lock(); _outbox.push_front(_currentMessage); mutex.unlock(); } ofLogError("Client::threadedFunction") << exc.name() << " : " << exc.displayText(); ErrorArgs args(exc, _currentMessage); ofNotifyEvent(events.onSMTPException, args, this); _currentMessage.reset(); } catch (Poco::Exception &exc) { if (_currentMessage) { mutex.lock(); _outbox.push_front(_currentMessage); mutex.unlock(); } ofLogError("Client::threadedFunction") << exc.name() << " : " << exc.displayText(); ErrorArgs args(exc, _currentMessage); ofNotifyEvent(events.onSMTPException, args, this); _currentMessage.reset(); } catch (std::exception& exc) { if (_currentMessage) { mutex.lock(); _outbox.push_front(_currentMessage); mutex.unlock(); } ofLogError("Client::threadedFunction") << exc.what(); ErrorArgs args(Poco::Exception(exc.what()), _currentMessage); ofNotifyEvent(events.onSMTPException, args, this); _currentMessage.reset(); } ofLogVerbose("Client::threadedFunction") << "Waiting for more messages."; _messageReady.wait(); _messageReady.reset(); } }