// sending command to remote replication daemon; specified command function // allows to specify which data is to be sent to the remote daemon void AbstractReplicatorStateMachine::sendCommand( int command, char* daemonSinfulString, CommandFunction function ) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand %s to %s\n", utilToString( command ), daemonSinfulString ); Daemon daemon( DT_ANY, daemonSinfulString ); ReliSock socket; // no retries after 'm_connectionTimeout' seconds of unsuccessful connection socket.timeout( m_connectionTimeout ); socket.doNotEnforceMinimalCONNECT_TIMEOUT( ); if( ! socket.connect( daemonSinfulString, 0, false ) ) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "unable to connect to %s\n", daemonSinfulString ); socket.close( ); return ; } // General actions for any command sending if( ! daemon.startCommand( command, &socket, m_connectionTimeout ) ) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "cannot start command %s to %s\n", utilToString( command ), daemonSinfulString ); socket.close( ); return ; } char const* sinfulString = daemonCore->InfoCommandSinfulString(); if(! socket.put( sinfulString )/* || ! socket.end_of_message( )*/) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "unable to code the local sinful string or eom%s\n", sinfulString ); socket.close( ); return ; } else { dprintf( D_FULLDEBUG, "AbstractReplicatorStateMachine::sendCommand " "local sinful string coded successfully\n" ); } // End of General actions for any command sending // Command-specific actions if( ! ((*this).*(function))( socket ) ) { socket.close( ); return ; } // End of Command-specific actions if( ! socket.end_of_message( ) ) { socket.close( ); dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "unable to code the end of message\n" ); return ; } socket.close( ); dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "%s command sent to %s successfully\n", utilToString( command ), daemonSinfulString ); }
/* Function : transferFileCommand * Return value: TRANSFERER_TRUE - upon success, * TRANSFERER_FALSE - upon failure * Description : sends a transfer command to the remote replication daemon, * which creates a uploading 'condor_transferer' process * Notes : sends to the replication daemon a port number, on which it * will be listening to the files uploading requests */ int DownloadReplicaTransferer::transferFileCommand( ) { char* temporaryDaemonSinfulString = const_cast<char*>( m_daemonSinfulString.Value( ) ); dprintf( D_ALWAYS, "DownloadReplicaTransferer::transferFileCommand " "to %s started\n", temporaryDaemonSinfulString ); Daemon daemon( DT_ANY, temporaryDaemonSinfulString ); ReliSock temporarySocket; // no retries after 'm_connectionTimeout' seconds of unsuccessful connection temporarySocket.timeout( m_connectionTimeout ); temporarySocket.doNotEnforceMinimalCONNECT_TIMEOUT( ); if( ! temporarySocket.connect( temporaryDaemonSinfulString, 0, false ) ) { dprintf( D_NETWORK, "DownloadReplicaTransferer::transferFileCommand " "unable to connect to %s, reason: %s\n", temporaryDaemonSinfulString, strerror( errno ) ); temporarySocket.close( ); return TRANSFERER_FALSE; } if( ! daemon.startCommand( REPLICATION_TRANSFER_FILE, &temporarySocket, m_connectionTimeout ) ) { dprintf( D_COMMAND, "DownloadReplicaTransferer::transferFileCommand " "unable to start command to addr %s\n", temporaryDaemonSinfulString ); temporarySocket.close( ); return TRANSFERER_FALSE; } MyString sinfulString; // find and bind port of the socket, to which the uploading // 'condor_transferer' process will send the important files ReliSock listeningSocket; listeningSocket.timeout( m_maxTransferLifetime / 2); //listeningSocket.timeout( ACCEPT_TIMEOUT ); //listeningSocket.timeout( m_connectionTimeout ); // this setting is practically unnecessary, since we do not connect to // remote sockets with 'listeningSocket' listeningSocket.doNotEnforceMinimalCONNECT_TIMEOUT( ); if( ! listeningSocket.bind( FALSE ) || ! listeningSocket.listen( ) ) { temporarySocket.close( ); listeningSocket.close( ); return TRANSFERER_FALSE; } sinfulString = listeningSocket.get_sinful_public(); // after the socket for the downloading/uploading process is occupied, // its number is sent to the remote replication daemon char* temporarySinfulString = const_cast<char*>( sinfulString.Value( ) ); if( ! temporarySocket.code( temporarySinfulString ) || ! temporarySocket.end_of_message( ) ) { dprintf( D_NETWORK, "DownloadReplicaTransferer::transferFileCommand " "unable to code the sinful string %s\n", temporarySinfulString ); temporarySocket.close( ); listeningSocket.close( ); return TRANSFERER_FALSE; } else { dprintf( D_ALWAYS, "DownloadReplicaTransferer::transferFileCommand " "sinful string %s coded successfully\n", temporarySinfulString ); } temporarySocket.close( ); m_socket = listeningSocket.accept( ); // m_socket->set_timeout_multiplier( 1 ); m_socket->timeout( INT_MAX ); //m_connectionTimeout ); m_socket->doNotEnforceMinimalCONNECT_TIMEOUT( ); listeningSocket.close( ); dprintf( D_ALWAYS, "DownloadReplicaTransferer::transferFileCommand " "sent transfer command successfully and accepted " "request on port no. %d\n", m_socket->get_port( ) ); return TRANSFERER_TRUE; }