/// =-=-=-=-=-=-=-
/// @brief function which sends the negotiation message
    error send_client_server_negotiation_message(
        irods::network_object_ptr _ptr,
        cs_neg_t&                  _cs_neg_msg ) {
        // =-=-=-=-=-=-=-
        // pack the negotiation message
        bytesBuf_t* cs_neg_buf = 0;
        int status = packStruct( &_cs_neg_msg,
                                 &cs_neg_buf,
                                 "CS_NEG_PI",
                                 RodsPackTable,
                                 0, XML_PROT );
        if ( status < 0 ) {
            return ERROR( status, "failed to pack client-server message" );
        }

        // =-=-=-=-=-=-=-
        // pack the negotiation message
        irods::error ret = sendRodsMsg( _ptr,
                                        RODS_CS_NEG_T,
                                        cs_neg_buf,
                                        0, 0, 0,
                                        XML_PROT );
        freeBBuf( cs_neg_buf );
        if ( !ret.ok() ) {
            return PASSMSG( "failed to send client-server negotiation message", ret );

        }

        return SUCCESS();

    } // send_client_server_negotiation_message
Example #2
0
irods::error sendVersion(
    irods::network_object_ptr _ptr,
    int                 versionStatus,
    int                 reconnPort,
    char*               reconnAddr,
    int                 cookie ) {
    version_t myVersion;
    int status;
    bytesBuf_t *versionBBuf = NULL;


    /* setup the version struct */

    memset( &myVersion, 0, sizeof( myVersion ) );
    myVersion.status = versionStatus;
    rstrcpy( myVersion.relVersion, RODS_REL_VERSION,  NAME_LEN );
    rstrcpy( myVersion.apiVersion, RODS_API_VERSION,  NAME_LEN );
    if ( reconnAddr != NULL ) {
        myVersion.reconnPort = reconnPort;
        rstrcpy( myVersion.reconnAddr, reconnAddr, LONG_NAME_LEN );
        myVersion.cookie = cookie;
    }
    else {
        // =-=-=-=-=-=-=-
        // super secret jargon irods detection
        // sshhhhhhh...
        myVersion.cookie = 400;

    }

    /* alway use XML for version */
    status = packStruct( ( char * ) &myVersion, &versionBBuf,
                         "Version_PI", RodsPackTable, 0, XML_PROT );
    if ( status < 0 ) {
        return ERROR( status, "packStruct error" );
    }

    irods::error ret = sendRodsMsg(
                           _ptr,
                           RODS_VERSION_T,
                           versionBBuf,
                           NULL, NULL, 0,
                           XML_PROT );
    freeBBuf( versionBBuf );
    if ( !ret.ok() ) {
        return PASS( ret );
    }

    return SUCCESS();

} // sendVersion
Example #3
0
// =-=-=-=-=-=-=-
// interface for requesting a reconnection
irods::error sendReconnMsg(
    irods::network_object_ptr _ptr,
    reconnMsg_t*        _msg ) {
    // =-=-=-=-=-=-=-
    // trap invalid param
    if ( _msg == NULL ) {
        return ERROR( USER__NULL_INPUT_ERR, "null msg buf" );
    }

    // =-=-=-=-=-=-=-
    // pack outgoing message - alway use XML for version
    bytesBuf_t* recon_buf = NULL;
    int status = packStruct(
                     static_cast<void*>( _msg ),
                     &recon_buf,
                     "ReconnMsg_PI",
                     RodsPackTable,
                     0, XML_PROT );
    if ( status < 0 ) {
        return ERROR( status, "failed to pack struct" );
    }

    // =-=-=-=-=-=-=-
    // pack outgoing message - alway use XML for version
    irods::error ret = sendRodsMsg(
                           _ptr,
                           RODS_RECONNECT_T,
                           recon_buf,
                           NULL,
                           NULL,
                           0,
                           XML_PROT );
    freeBBuf( recon_buf );
    if ( !ret.ok() ) {
        rodsLogError( LOG_ERROR, status,
                      "sendReconnMsg: sendRodsMsg of reconnect msg failed, status = %d",
                      status );
    }

    return CODE( status );

} // sendReconnMsg
Example #4
0
int rsApiHandler(
    rsComm_t*   rsComm,
    int         apiNumber,
    bytesBuf_t* inputStructBBuf,
    bytesBuf_t* bsBBuf ) {
    int apiInx;
    int status = 0;
    char *myInStruct = NULL;
    funcPtr myHandler = NULL;
    void *myOutStruct = NULL;
    bytesBuf_t myOutBsBBuf;
    int retVal = 0;
    int numArg = 0;
    void *myArgv[4];
    memset( &myOutBsBBuf, 0, sizeof( bytesBuf_t ) );
    memset( &rsComm->rError, 0, sizeof( rError_t ) );

    apiInx = apiTableLookup( apiNumber );

    // =-=-=-=-=-=-=-
    // create a network object
    irods::network_object_ptr net_obj;
    irods::error ret = irods::network_factory( rsComm, net_obj );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return apiInx;
    }

    if ( apiInx < 0 ) {
        rodsLog( LOG_ERROR,
                 "rsApiHandler: apiTableLookup of apiNumber %d failed", apiNumber );
        /* cannot use sendApiReply because it does not know apiInx */
        sendRodsMsg( net_obj, RODS_API_REPLY_T, NULL, NULL, NULL,
                     apiInx, rsComm->irodsProt );
        return apiInx;
    }

    rsComm->apiInx = apiInx;

    status = chkApiVersion( apiInx );
    if ( status < 0 ) {
        sendApiReply( rsComm, apiInx, status, myOutStruct, &myOutBsBBuf );
        return status;
    }

    status = chkApiPermission( rsComm, apiInx );
    if ( status < 0 ) {
        rodsLog( LOG_NOTICE,
                 "rsApiHandler: User has no permission for apiNumber %d", apiNumber );
        sendApiReply( rsComm, apiInx, status, myOutStruct, &myOutBsBBuf );
        return status;
    }

    irods::api_entry_table& RsApiTable = irods::get_server_api_table();

    /* some sanity check */
    if ( inputStructBBuf->len > 0 && RsApiTable[apiInx]->inPackInstruct == NULL ) {
        rodsLog( LOG_NOTICE,
                 "rsApiHandler: input struct error 1 for apiNumber %d", apiNumber );
        sendApiReply( rsComm, apiInx, SYS_API_INPUT_ERR, myOutStruct,
                      &myOutBsBBuf );
        return SYS_API_INPUT_ERR;
    }

    if ( inputStructBBuf->len <= 0 && RsApiTable[apiInx]->inPackInstruct != NULL ) {
        rodsLog( LOG_NOTICE,
                 "rsApiHandler: input struct error 2 for apiNumber %d", apiNumber );
        sendApiReply( rsComm, apiInx, SYS_API_INPUT_ERR, myOutStruct,
                      &myOutBsBBuf );
        return SYS_API_INPUT_ERR;
    }

    if ( bsBBuf->len > 0 && RsApiTable[apiInx]->inBsFlag <= 0 ) {
        rodsLog( LOG_NOTICE,
                 "rsApiHandler: input byte stream error for apiNumber %d", apiNumber );
        sendApiReply( rsComm, apiInx, SYS_API_INPUT_ERR, myOutStruct,
                      &myOutBsBBuf );
        return SYS_API_INPUT_ERR;
    }

    if ( inputStructBBuf->len > 0 ) {
        status = unpackStruct( inputStructBBuf->buf, ( void ** )( static_cast< void * >( &myInStruct ) ),
                               ( char* )RsApiTable[apiInx]->inPackInstruct, RodsPackTable, rsComm->irodsProt );
        if ( status < 0 ) {
            rodsLog( LOG_NOTICE,
                     "rsApiHandler: unpackStruct error for apiNumber %d, status = %d",
                     apiNumber, status );
            sendApiReply( rsComm, apiInx, status, myOutStruct,
                          &myOutBsBBuf );
            return status;
        }
    }

    /* ready to call the handler functions */

    myHandler = RsApiTable[apiInx]->svrHandler;
    if ( !myHandler ) {
        rodsLog( LOG_ERROR, "Null handler encountered for api number %d in rsApiHandler.", apiNumber );
        return SYS_API_INPUT_ERR;
    }

    if ( RsApiTable[apiInx]->inPackInstruct != NULL ) {
        myArgv[numArg] = myInStruct;
        numArg++;
    };

    if ( RsApiTable[apiInx]->inBsFlag != 0 ) {
        myArgv[numArg] = bsBBuf;
        numArg++;
    };

    if ( RsApiTable[apiInx]->outPackInstruct != NULL ) {
        myArgv[numArg] = ( void * ) &myOutStruct;
        numArg++;
    };

    if ( RsApiTable[apiInx]->outBsFlag != 0 ) {
        myArgv[numArg] = ( void * ) &myOutBsBBuf;
        numArg++;
    };

    if ( numArg == 0 ) {
        retVal = ( *myHandler )( rsComm );
    }
    else if ( numArg == 1 ) {
        retVal = ( *myHandler )( rsComm, myArgv[0] );
    }
    else if ( numArg == 2 ) {
        retVal = ( *myHandler )( rsComm, myArgv[0], myArgv[1] );
    }
    else if ( numArg == 3 ) {
        retVal = ( *myHandler )( rsComm, myArgv[0], myArgv[1], myArgv[2] );
    }
    else if ( numArg == 4 ) {
        retVal = ( *myHandler )( rsComm, myArgv[0], myArgv[1], myArgv[2],
                                 myArgv[3] );
    }

    if ( retVal != SYS_NO_HANDLER_REPLY_MSG ) {
        status = sendAndProcApiReply
                 ( rsComm, apiInx, retVal, myOutStruct, &myOutBsBBuf );
    }

    // =-=-=-=-=-=-=-
    // clear the incoming packing instruction
    if ( myInStruct != NULL ) {
        if ( RsApiTable[apiInx]->clearInStruct ) {
            RsApiTable[apiInx]->clearInStruct( myInStruct );
        }

        free( myInStruct );
        myInStruct = NULL;
    }

    if ( retVal >= 0 && status < 0 ) {
        return status;
    }
    else {
        return retVal;
    }
}
Example #5
0
int
sendApiReply( rsComm_t * rsComm, int apiInx, int retVal,
              void * myOutStruct, bytesBuf_t * myOutBsBBuf ) {
    int status = 0;
    bytesBuf_t *outStructBBuf = NULL;
    bytesBuf_t *myOutStructBBuf;
    bytesBuf_t *rErrorBBuf = NULL;
    bytesBuf_t *myRErrorBBuf;

//#ifndef windows_platform
    svrChkReconnAtSendStart( rsComm );
//#endif

    if ( retVal == SYS_HANDLER_DONE_NO_ERROR ) {
        /* not actually an error */
        retVal = 0;
    }

    // =-=-=-=-=-=-=-
    // create a network object
    irods::network_object_ptr net_obj;
    irods::error ret = irods::network_factory( rsComm, net_obj );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return ret.code();

    }


    irods::api_entry_table& RsApiTable = irods::get_server_api_table();
    if ( RsApiTable[apiInx]->outPackInstruct != NULL && myOutStruct != NULL ) {

        status = packStruct( ( char * ) myOutStruct, &outStructBBuf,
                             ( char* )RsApiTable[apiInx]->outPackInstruct, RodsPackTable, FREE_POINTER,
                             rsComm->irodsProt );

        if ( status < 0 ) {
            rodsLog( LOG_NOTICE,
                     "sendApiReply: packStruct error, status = %d", status );
            sendRodsMsg( net_obj, RODS_API_REPLY_T, NULL,
                         NULL, NULL, status, rsComm->irodsProt );
            svrChkReconnAtSendEnd( rsComm );
            return status;
        }

        myOutStructBBuf = outStructBBuf;
    }
    else {
        myOutStructBBuf = NULL;
    }

    if ( RsApiTable[apiInx]->outBsFlag == 0 ) {
        myOutBsBBuf = NULL;
    }

    if ( rsComm->rError.len > 0 ) {
        status = packStruct( ( char * ) &rsComm->rError, &rErrorBBuf,
                             "RError_PI", RodsPackTable, 0, rsComm->irodsProt );

        if ( status < 0 ) {
            rodsLog( LOG_NOTICE,
                     "sendApiReply: packStruct error, status = %d", status );
            sendRodsMsg( net_obj, RODS_API_REPLY_T, NULL,
                         NULL, NULL, status, rsComm->irodsProt );
            svrChkReconnAtSendEnd( rsComm );
            freeBBuf( outStructBBuf );
            freeBBuf( rErrorBBuf );
            return status;
        }

        myRErrorBBuf = rErrorBBuf;
    }
    else {
        myRErrorBBuf = NULL;
    }
    ret = sendRodsMsg( net_obj, RODS_API_REPLY_T, myOutStructBBuf,
                       myOutBsBBuf, myRErrorBBuf, retVal, rsComm->irodsProt );
    if ( !ret.ok() ) {
        int status1;
        irods::log( PASS( ret ) );

        if ( rsComm->reconnSock > 0 ) {
            int savedStatus = ret.code();
            boost::unique_lock< boost::mutex > boost_lock( *rsComm->thread_ctx->lock );
            rodsLog( LOG_DEBUG,
                     "sendApiReply: svrSwitchConnect. cliState = %d,agState=%d",
                     rsComm->clientState, rsComm->agentState );
            status1 = svrSwitchConnect( rsComm );
            boost_lock.unlock();
            if ( status1 > 0 ) {
                /* should not be here */
                rodsLog( LOG_NOTICE,
                         "sendApiReply: Switch connection and retry sendRodsMsg" );
                ret = sendRodsMsg( net_obj, RODS_API_REPLY_T,
                                   myOutStructBBuf, myOutBsBBuf, myRErrorBBuf,
                                   retVal, rsComm->irodsProt );

                if ( ret.code() >= 0 ) {
                    rodsLog( LOG_NOTICE,
                             "sendApiReply: retry sendRodsMsg succeeded" );
                }
                else {
                    status = savedStatus;
                }
            }
        }
    }

    svrChkReconnAtSendEnd( rsComm );

    freeBBuf( outStructBBuf );
    freeBBuf( rErrorBBuf );

    return status;
}
Example #6
0
int
sendStartupPack( rcComm_t *conn, int connectCnt, int reconnFlag ) {
    startupPack_t startupPack;
    int status;
    char *tmpStr;
    bytesBuf_t *startupPackBBuf = NULL;


    /* setup the startup pack */

    startupPack.irodsProt  = conn->irodsProt;
    startupPack.connectCnt = connectCnt;
    startupPack.reconnFlag = reconnFlag;

    rstrcpy( startupPack.proxyUser,      conn->proxyUser.userName,  NAME_LEN );
    rstrcpy( startupPack.proxyRodsZone,  conn->proxyUser.rodsZone,  NAME_LEN );
    rstrcpy( startupPack.clientUser,     conn->clientUser.userName, NAME_LEN );
    rstrcpy( startupPack.clientRodsZone, conn->clientUser.rodsZone, NAME_LEN );

    rstrcpy( startupPack.relVersion, RODS_REL_VERSION,  NAME_LEN );
    rstrcpy( startupPack.apiVersion, RODS_API_VERSION,  NAME_LEN );

    if ( ( tmpStr = getenv( SP_OPTION ) ) != NULL ) {
        rstrcpy( startupPack.option, tmpStr, NAME_LEN );
    }
    else {
        startupPack.option[0] = '\0';
    }

    // =-=-=-=-=-=-=-
    // if the advanced negotiation is requested from the irodsEnv,
    // tack those results onto the startup pack option string
    rodsEnv rods_env;
    status = getRodsEnv( &rods_env );

    if ( status >= 0 && strlen( rods_env.rodsClientServerNegotiation ) > 0 ) {
        strncat( startupPack.option,
                 rods_env.rodsClientServerNegotiation,
                 strlen( rods_env.rodsClientServerNegotiation ) );
    }

    /* always use XML_PROT for the startupPack */
    status = packStruct( ( void * ) &startupPack, &startupPackBBuf,
                         "StartupPack_PI", RodsPackTable, 0, XML_PROT );
    if ( status < 0 ) {
        rodsLogError( LOG_NOTICE, status,
                      "sendStartupPack: packStruct error, status = %d", status );
        return status;
    }

    irods::network_object_ptr net_obj;
    irods::error ret = irods::network_factory( conn, net_obj );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        freeBBuf( startupPackBBuf );
        return ret.code();
    }

    ret = sendRodsMsg(
              net_obj,
              RODS_CONNECT_T,
              startupPackBBuf,
              NULL, NULL, 0,
              XML_PROT );
    freeBBuf( startupPackBBuf );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return ret.code();
    }

    return ret.code();

} // sendStartupPack
Example #7
0
// =-=-=-=-=-=-=-
// request shut down client-server connection
int rcDisconnect(
    rcComm_t* _conn ) {
    // =-=-=-=-=-=-=-
    // check for invalid param
    if ( _conn == NULL ) {
        return 0;
    }

    // =-=-=-=-=-=-=-
    // create network object to pass to plugin interface
    irods::network_object_ptr net_obj;
    irods::error ret = irods::network_factory( _conn, net_obj );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return ret.code();
    }

    // =-=-=-=-=-=-=-
    // send disconnect msg to agent
    ret = sendRodsMsg(
              net_obj,
              RODS_DISCONNECT_T,
              NULL, NULL, NULL, 0,
              _conn->irodsProt );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
    }

    // =-=-=-=-=-=-=-
    // get rods env to pass to client start for policy decisions
    rodsEnv rods_env;
    int status = getRodsEnv( &rods_env );

    // =-=-=-=-=-=-=-
    // shut down any network plugin activity
    ret = sockClientStop( net_obj, &rods_env );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
    }

    net_obj->to_client( _conn );

    close( _conn->sock );


    _conn->exit_flg = true; //
    if ( _conn->thread_ctx->reconnThr ) {
        try {
            // force an interruption point
            _conn->exit_flg = true;
            bool val = _conn->thread_ctx->reconnThr->try_join_for( 
                           boost::chrono::seconds( 
                               2 ) );
            if( true != val ) {
                // do not error out to client
            }

        }
        catch ( const boost::thread_interrupted& ) {
            rodsLog( LOG_ERROR, "Thread encountered interrupt." );
            status = SYS_THREAD_ENCOUNTERED_INTERRUPT;
        }
        catch ( const boost::thread_resource_error& ) {
            rodsLog( LOG_ERROR, "Threads exceed maximum supported concurrent threads" );
            status = SYS_INTERNAL_ERR;
        }
    }

    status = freeRcComm( _conn );

    return status;

} // rcDisconnect
int
sendApiRequest( rcComm_t *conn, int apiInx, void *inputStruct,
                bytesBuf_t *inputBsBBuf ) {
    int status = 0;
    bytesBuf_t *inputStructBBuf = NULL;
    bytesBuf_t *myInputStructBBuf = NULL;

    cliChkReconnAtSendStart( conn );

    irods::api_entry_table& RcApiTable = irods::get_client_api_table();

    irods::api_entry_table::iterator itr = RcApiTable.find( apiInx );
    if ( itr == RcApiTable.end() ) {
        rodsLogError( LOG_ERROR, SYS_UNMATCHED_API_NUM, "API Entry not found at index %d", apiInx );
        return SYS_UNMATCHED_API_NUM;
    }


    if ( RcApiTable[apiInx]->inPackInstruct != NULL ) {
        if ( inputStruct == NULL ) {
            cliChkReconnAtSendEnd( conn );
            return ( USER_API_INPUT_ERR );
        }
        status = packStruct( ( void * ) inputStruct, &inputStructBBuf,
                             ( char* )RcApiTable[apiInx]->inPackInstruct, RodsPackTable, 0, conn->irodsProt );
        if ( status < 0 ) {
            rodsLogError( LOG_ERROR, status,
                          "sendApiRequest: packStruct error, status = %d", status );
            cliChkReconnAtSendEnd( conn );
            return status;
        }

        myInputStructBBuf = inputStructBBuf;
    }
    else {
        myInputStructBBuf = NULL;
    };


    if ( RcApiTable[apiInx]->inBsFlag <= 0 ) {
        inputBsBBuf = NULL;
    }

    irods::network_object_ptr net_obj;
    irods::error ret = irods::network_factory( conn, net_obj );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return ret.code();
    }

    ret = sendRodsMsg(
              net_obj,
              RODS_API_REQ_T,
              myInputStructBBuf,
              inputBsBBuf,
              NULL,
              RcApiTable[apiInx]->apiNumber,
              conn->irodsProt );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        if ( conn->svrVersion != NULL &&
                conn->svrVersion->reconnPort > 0 ) {
            int status1;
            int savedStatus = ret.code() ;
            conn->thread_ctx->lock->lock();
            status1 = cliSwitchConnect( conn );
            rodsLog( LOG_DEBUG,
                     "sendApiRequest: svrSwitchConnect. cliState = %d,agState=%d",
                     conn->clientState, conn->agentState );
            conn->thread_ctx->lock->unlock();
            if ( status1 > 0 ) {
                /* should not be here */
                rodsLog( LOG_NOTICE,
                         "sendApiRequest: Switch connection and retry sendRodsMsg" );
                ret = sendRodsMsg(
                          net_obj,
                          RODS_API_REQ_T,
                          myInputStructBBuf,
                          inputBsBBuf,
                          NULL,
                          RcApiTable[apiInx]->apiNumber,
                          conn->irodsProt );
                if ( !ret.ok() ) {
                    irods::log( PASS( ret ) );
                }
                else {
                    status = savedStatus;
                }

            } // if status1 > 0

        } // if svrVersion != NULL ...

    }
    else {
        // =-=-=-=-=-=-=-
        // be sure to pass along the return code from the
        // plugin call
        status = ret.code();

    }

    freeBBuf( inputStructBBuf );

    return ( status );
}