FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GitHub Viewer

/* * HTTPSConnection.cpp * * Created on: Dec 6, 2017 * Author: frank */ #include "HTTPSConnection.hpp" namespace httpsserver { HTTPSConnection::HTTPSConnection(ResourceResolver * resResolver): _resResolver(resResolver) { _socket = -1; _addrLen = 0; _ssl = NULL; _bufferProcessed = 0; _bufferUnusedIdx = 0; _connectionState = STATE_UNDEFINED; _clientState = CSTATE_UNDEFINED; _httpHeaders = NULL; _defaultHeaders = NULL; _isKeepAlive = false; _lastTransmissionTS = millis(); _shutdownTS = 0; } HTTPSConnection::~HTTPSConnection() { // Close the socket closeConnection(); } /** * Initializes the connection from a server socket. * * The call WILL BLOCK if accept(serverSocketID) blocks. So use select() to check for that in advance. */ int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders) { if (_connectionState == STATE_UNDEFINED) { _defaultHeaders = defaultHeaders; _socket = accept(serverSocketID, (struct sockaddr * )&_sockAddr, &_addrLen); // Build up SSL Connection context if the socket has been created successfully if (_socket >= 0) { HTTPS_DLOGHEX("[-->] New connection. Socket fid is: ", _socket); _ssl = SSL_new(sslCtx); if (_ssl) { // Bind SSL to the socket int success = SSL_set_fd(_ssl, _socket); if (success) { // Perform the handshake success = SSL_accept(_ssl); if (success) { _connectionState = STATE_INITIAL; _httpHeaders = new HTTPHeaders(); refreshTimeout(); return _socket; } else { HTTPS_DLOG("[ERR] SSL_accept failed. Aborting handshake."); } } else { HTTPS_DLOG("[ERR] SSL_set_fd failed. Aborting handshake."); } } else { HTTPS_DLOG("[ERR] SSL_new failed. Aborting handshake."); } } else { HTTPS_DLOG("[ERR] Could not accept() new connection"); } _connectionState = STATE_ERROR; _clientState = CSTATE_ACTIVE; // This will only be called if the connection could not be established and cleanup // variables like _ssl etc. closeConnection(); } // Error: The connection has already been established or could not be established return -1; } /** * True if the connection is timed out. * * (Should be checkd in the loop and transition should go to CONNECTION_CLOSE if exceeded) */ bool HTTPSConnection::isTimeoutExceeded() { return _lastTransmissionTS + HTTPS_CONNECTION_TIMEOUT < millis(); } /** * Resets the timeout to allow again the full HTTPS_CONNECTION_TIMEOUT milliseconds */ void HTTPSConnection::refreshTimeout() { _lastTransmissionTS = millis(); } /** * Returns true, if the connection has been closed. */ bool HTTPSConnection::isClosed() { return (_connectionState == STATE_ERROR || _connectionState == STATE_CLOSED); } /** * Returns true, if the connection has been closed due to error */ bool HTTPSConnection::isError() { return (_connectionState == STATE_ERROR); } void HTTPSConnection::closeConnection() { // TODO: Call an event handler here, maybe? if (_connectionState != STATE_ERROR && _connectionState != STATE_CLOSED) { // First call to closeConnection - set the timestamp to calculate the timeout later on if (_connectionState != STATE_CLOSING) { _shutdownTS = millis(); } // Set the connection state to closing. We stay in closing as long as SSL has not been shutdown // correctly _connectionState = STATE_CLOSING; } // Try to tear down SSL while we are in the _shutdownTS timeout period or if an error occurred if (_ssl) { if(_connectionState == STATE_ERROR || SSL_shutdown(_ssl) == 0) { // SSL_shutdown will return 1 as soon as the client answered with close notify // This means we are safe to close the socket SSL_free(_ssl); _ssl = NULL; } else if (_shutdownTS + HTTPS_SHUTDOWN_TIMEOUT < millis()) { // The timeout has been hit, we force SSL shutdown now by freeing the context SSL_free(_ssl); _ssl = NULL; HTTPS_DLOG("[ERR] SSL_shutdown did not receive close notification from the client"); _connectionState = STATE_ERROR; } } // If SSL has been brought down, close the socket if (!_ssl) { // Tear down the socket if (_socket >= 0) { HTTPS_DLOGHEX("[

Back | FazBrowse Home | New Git URL