Esempio n. 1
0
/*
    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);
        }
    }
}
Esempio n. 2
0
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()));
}
Esempio n. 3
0
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();
    }
}