/** * Called when timer set up in the schedule function goes off. */ void ScrobblerSubmitter::scheduledTimeReached() { if ( m_needHandshake || m_challenge.isEmpty() ) performHandshake(); else performSubmit(); }
/** * Schedules an Audioscrobbler handshake or submit as required. * Returns true if an immediate submit was possible */ bool ScrobblerSubmitter::schedule( bool failure ) { m_timer.stop(); if ( m_inProgress || !canSubmit() ) return false; uint when, currentTime = QDateTime::currentDateTime( Qt::UTC ).toTime_t(); if ( currentTime - m_prevSubmitTime > m_interval ) when = 0; else when = m_interval - ( currentTime - m_prevSubmitTime ); if ( failure ) { m_backoff = kMin( kMax( m_backoff * 2, unsigned( MIN_BACKOFF ) ), unsigned( MAX_BACKOFF ) ); when = kMax( m_backoff, m_interval ); } else m_backoff = 0; if ( m_needHandshake || m_challenge.isEmpty() ) { m_challenge = QString::null; m_needHandshake = false; if ( when == 0 ) { debug() << "Performing immediate handshake" << endl; performHandshake(); } else { debug() << "Performing handshake in " << when << " seconds" << endl; m_timer.start( when * 1000, true ); } } else if ( !m_submitQueue.isEmpty() || !m_holdFakeQueue && !m_fakeQueue.isEmpty() ) { // if we only have stuff in the fake queue, we need to only schedule for when we can actually do something with it if ( m_submitQueue.isEmpty() && m_lastSubmissionFinishTime + m_fakeQueue.getFirst()->length() > currentTime + when ) when = m_lastSubmissionFinishTime + m_fakeQueue.getFirst()->length() - currentTime; if ( when == 0 ) { debug() << "Performing immediate submit" << endl; performSubmit(); return true; } else { debug() << "Performing submit in " << when << " seconds" << endl; m_timer.start( when * 1000, true ); } } else { debug() << "Nothing to schedule" << endl; } return false; }
/* Recursive handshake */ static int32 performHandshake(sslConn_t *sendingSide, sslConn_t *receivingSide) { unsigned char *inbuf, *outbuf, *plaintextBuf; int32 inbufLen, outbufLen, rc, sdrc, dataSent; uint32 ptLen; #ifdef ENABLE_PERF_TIMING psTime_t start, end; #endif /* ENABLE_PERF_TIMING */ /* Sending side will have outdata ready */ #ifdef ENABLE_PERF_TIMING psGetTime(&start); #endif /* ENABLE_PERF_TIMING */ outbufLen = matrixSslGetOutdata(sendingSide->ssl, &outbuf); #ifdef ENABLE_PERF_TIMING psGetTime(&end); sendingSide->runningTime += psDiffMsecs(start, end); #endif /* ENABLE_PERF_TIMING */ /* Receiving side must ask for storage space to receive data into */ #ifdef ENABLE_PERF_TIMING psGetTime(&start); #endif /* ENABLE_PERF_TIMING */ inbufLen = matrixSslGetReadbuf(receivingSide->ssl, &inbuf); #ifdef ENABLE_PERF_TIMING psGetTime(&end); receivingSide->runningTime += psDiffMsecs(start, end); #endif /* ENABLE_PERF_TIMING */ /* The indata is the outdata from the sending side. copy it over */ dataSent = min(outbufLen, inbufLen); memcpy(inbuf, outbuf, dataSent); /* Now update the sending side that data has been "sent" */ #ifdef ENABLE_PERF_TIMING psGetTime(&start); #endif /* ENABLE_PERF_TIMING */ sdrc = matrixSslSentData(sendingSide->ssl, dataSent); #ifdef ENABLE_PERF_TIMING psGetTime(&end); sendingSide->runningTime += psDiffMsecs(start, end); #endif /* ENABLE_PERF_TIMING */ /* Received data */ #ifdef ENABLE_PERF_TIMING psGetTime(&start); #endif /* ENABLE_PERF_TIMING */ rc = matrixSslReceivedData(receivingSide->ssl, dataSent, &plaintextBuf, &ptLen); #ifdef ENABLE_PERF_TIMING psGetTime(&end); receivingSide->runningTime += psDiffMsecs(start, end); #endif /* ENABLE_PERF_TIMING */ if (rc == MATRIXSSL_REQUEST_SEND) { /* Success case. Switch roles and continue */ return performHandshake(receivingSide, sendingSide); } else if (rc == MATRIXSSL_REQUEST_RECV) { /* This pass didn't take care of it all. Don't switch rolls and try again */ return performHandshake(sendingSide, receivingSide); } else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) { return PS_SUCCESS; } else if (rc == MATRIXSSL_RECEIVED_ALERT) { /* Just continue if warning level alert */ if (plaintextBuf[0] == SSL_ALERT_LEVEL_WARNING) { if (matrixSslProcessedData(receivingSide->ssl, &plaintextBuf, &ptLen) != 0) { return PS_FAILURE; } return performHandshake(sendingSide, receivingSide); } else { return PS_FAILURE; } } else { printf("Unexpected error in performHandshake: %d\n", rc); return PS_FAILURE; } return PS_FAILURE; /* can't get here */ }
int main(int argc, char **argv) { int32 id; sslConn_t *svrConn, *clnConn; #ifdef ENABLE_PERF_TIMING int32 perfIter; uint32 clnTime, svrTime; #endif /* ENABLE_PERF_TIMING */ if (matrixSslOpen() < 0) { fprintf(stderr, "matrixSslOpen failed, exiting..."); } svrConn = psMalloc(PEERSEC_NO_POOL, sizeof(sslConn_t)); clnConn = psMalloc(PEERSEC_NO_POOL, sizeof(sslConn_t)); memset(svrConn, 0, sizeof(sslConn_t)); memset(clnConn, 0, sizeof(sslConn_t)); for (id = 0; ciphers[id].cipherId > 0; id++) { matrixSslInitSessionId(clientSessionId); _psTraceStr("Testing %s suite\n", ciphers[id].name); /* Standard Handshake */ _psTrace(" Standard handshake test\n"); #ifdef ENABLE_PERF_TIMING /* Each matrixSsl call in the handshake is wrapped by a timer. The data exchange phase is not being included in the time */ clnTime = svrTime = 0; for (perfIter = 0; perfIter < CONN_ITER; perfIter++) { #endif /* ENABLE_PERF_TIMING */ if (initializeHandshake(clnConn, svrConn, ciphers[id], &clientSessionId) < 0) { _psTrace(" FAILED: initializing Standard handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Standard handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Standard handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } #ifdef ENABLE_PERF_TIMING clnTime += clnConn->runningTime; svrTime += svrConn->runningTime; /* Have to reset conn for full handshake... except last time through */ if (perfIter + 1 != CONN_ITER) { matrixSslDeleteSession(clnConn->ssl); matrixSslDeleteSession(svrConn->ssl); matrixSslInitSessionId(clientSessionId); } } /* iteration loop close */ _psTraceInt("CLIENT: %d " TIME_UNITS, (int32)clnTime/CONN_ITER); _psTraceInt("SERVER: %d " TIME_UNITS, (int32)svrTime/CONN_ITER); // _psTrace("Press any key to continue tests"); _psTrace("\n==========\n"); // getchar(); #endif /* ENABLE_PERF_TIMING */ #ifdef SSL_REHANDSHAKES_ENABLED /* Re-Handshake (full handshake over existing connection) */ _psTrace(" Re-handshake test (client-initiated)\n"); if (initializeReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } #else _psTrace(" Re-handshake tests are disabled (ENABLE_SECURE_REHANDSHAKES)\n"); #endif /* Resumed handshake (fast handshake over new connection) */ _psTrace(" Resumed handshake test (new connection)\n"); #ifdef ENABLE_PERF_TIMING clnTime = svrTime = 0; for (perfIter = 0; perfIter < CONN_ITER; perfIter++) { #endif /* ENABLE_PERF_TIMING */ if (initializeResumedHandshake(clnConn, svrConn, ciphers[id]) < 0) { _psTrace(" FAILED: initializing Resumed handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Resumed handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Resumed handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } #ifdef ENABLE_PERF_TIMING clnTime += clnConn->runningTime; svrTime += svrConn->runningTime; /* Have to reset conn for full handshake */ } /* iteration loop */ _psTraceInt("CLIENT: %d " TIME_UNITS, (int32)clnTime/CONN_ITER); _psTraceInt("SERVER: %d " TIME_UNITS, (int32)svrTime/CONN_ITER); _psTrace("Press any key to continue tests"); _psTrace("\n==========\n"); // getchar(); #endif /* ENABLE_PERF_TIMING */ #ifdef SSL_REHANDSHAKES_ENABLED /* Re-handshake initiated by server (full handshake over existing conn) */ _psTrace(" Re-handshake test (server initiated)\n"); if (initializeServerInitiatedReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing Re-handshake\n"); goto LBL_FREE; } if (performHandshake(svrConn, clnConn) < 0) { _psTrace(" FAILED: Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Resumed re-handshake (fast handshake over existing connection) */ _psTrace(" Resumed Re-handshake test (client initiated)\n"); if (initializeResumedReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing Resumed Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Resumed Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Resumed Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Resumed re-handshake initiated by server (fast handshake over conn) */ _psTrace(" Resumed Re-handshake test (server initiated)\n"); if (initializeServerInitiatedResumedReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing Resumed Re-handshake\n"); goto LBL_FREE; } if (performHandshake(svrConn, clnConn) < 0) { _psTrace(" FAILED: Resumed Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Resumed Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Re-handshaking with "upgraded" parameters */ _psTrace(" Change cert callback Re-handshake test\n"); if (initializeUpgradeCertCbackReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: init upgrade certCback Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Upgrade cert callback Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Upgrade cert callback Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Upgraded keys */ _psTrace(" Change keys Re-handshake test\n"); if (initializeUpgradeKeysReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: init upgrade keys Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Upgrade keys Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Upgrade keys Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Change cipher spec test. Changing to a hardcoded RSA suite so this will not work on suites that don't have RSA material loaded */ if (ciphers[id].rsa == 1) { _psTrace(" Change cipher suite Re-handshake test\n"); if (initializeChangeCipherReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: init change cipher Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Change cipher suite Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Change cipher suite Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } } #endif /* !SSL_REHANDSHAKES_ENABLED */ LBL_FREE: freeSessionAndConnection(svrConn); freeSessionAndConnection(clnConn); } psFree(svrConn); psFree(clnConn); matrixSslClose(); #ifdef WIN32 _psTrace("Press any key to close"); getchar(); #endif return PS_SUCCESS; }
void Subscriber::startListening(QString _commandsUrl, QString _eventsUrl) { this->commandUrl = _commandsUrl; this->eventServerUrl = _eventsUrl; performHandshake(); }