コード例 #1
0
ファイル: rsApiHandler.cpp プロジェクト: hurngchunlee/irods
int
readAndProcClientMsg( rsComm_t * rsComm, int flags ) {
    int status = 0;
    msgHeader_t myHeader;
    bytesBuf_t inputStructBBuf, bsBBuf, errorBBuf;

    bzero( &inputStructBBuf, sizeof( inputStructBBuf ) );
    bzero( &bsBBuf, sizeof( bsBBuf ) );
    bzero( &errorBBuf, sizeof( errorBBuf ) );

    svrChkReconnAtReadStart( rsComm );
    /* everything else are set in readMsgBody */

    /* read the header */

    // =-=-=-=-=-=-=-
    // 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();
    }

    if ( ( flags & READ_HEADER_TIMEOUT ) != 0 ) {
        int retryCnt = 0;
        struct timeval tv;
        tv.tv_sec = READ_HEADER_TIMEOUT_IN_SEC;
        tv.tv_usec = 0;

        while ( 1 ) {
            ret = readMsgHeader( net_obj, &myHeader, &tv );
            if ( !ret.ok() ) {
                if ( isL1descInuse() && retryCnt < MAX_READ_HEADER_RETRY ) {
                    rodsLogError( LOG_ERROR, status,
                                  "readAndProcClientMsg:readMsgHeader error. status = %d",  ret.code() );
                    retryCnt++;
                    continue;
                }
                if ( ret.code() == USER_SOCK_CONNECT_TIMEDOUT ) {
                    rodsLog( LOG_ERROR,
                             "readAndProcClientMsg: readMsgHeader by pid %d timedout",
                             getpid() );
                    return  ret.code();
                }
            }
            break;
        } // while 1
    }
    else {
        ret = readMsgHeader( net_obj, &myHeader, NULL );
    }

    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        /* attempt to accept reconnect. ENOENT result  from * user cntl-C */
        if ( rsComm->reconnSock > 0 ) {
            int savedStatus = ret.code();
            /* try again. the socket might have changed */
            boost::unique_lock< boost::mutex > boost_lock( *rsComm->thread_ctx->lock );
            rodsLog( LOG_DEBUG,
                     "readAndProcClientMsg: svrSwitchConnect. cliState = %d,agState=%d",
                     rsComm->clientState, rsComm->agentState );
            svrSwitchConnect( rsComm );
            boost_lock.unlock();
            ret = readMsgHeader( net_obj, &myHeader, NULL );
            if ( !ret.ok() ) {
                svrChkReconnAtReadEnd( rsComm );
                return savedStatus;
            }
        }
        else {
            svrChkReconnAtReadEnd( rsComm );
            return ret.code();
        }
    } // if !ret.ok()

#ifdef SYS_TIMING
    if ( strcmp( myHeader.type, RODS_API_REQ_T ) == 0 ) {
        /* Get the total time of AUTH_REQUEST_AN and AUTH_RESPONSE_AN */
        if ( myHeader.intInfo != AUTH_RESPONSE_AN ) {
            initSysTiming( "irodsAgent", "recv request", 0 );
        }
    }
#endif
    ret = readMsgBody( net_obj, &myHeader, &inputStructBBuf,
                       &bsBBuf, &errorBBuf, rsComm->irodsProt, NULL );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        svrChkReconnAtReadEnd( rsComm );
        return ret.code();
    }

    svrChkReconnAtReadEnd( rsComm );

    /* handler switch by msg type */

    if ( strcmp( myHeader.type, RODS_API_REQ_T ) == 0 ) {
        status = rsApiHandler( rsComm, myHeader.intInfo, &inputStructBBuf,
                               &bsBBuf );
#ifdef SYS_TIMING
        char tmpStr[NAME_LEN];
        snprintf( tmpStr, NAME_LEN, "handle API %d", myHeader.intInfo );
        printSysTiming( "irodsAgent", tmpStr, 0 );
#endif
        clearBBuf( &inputStructBBuf );
        clearBBuf( &bsBBuf );
        clearBBuf( &errorBBuf );

        if ( ( flags & RET_API_STATUS ) != 0 ) {
            return status;
        }
        else {
            return 0;
        }
    }
    else if ( strcmp( myHeader.type, RODS_DISCONNECT_T ) == 0 ) {
        rodsLog( LOG_NOTICE,
                 "readAndProcClientMsg: received disconnect msg from client" );

        return DISCONN_STATUS;
    }
    else if ( strcmp( myHeader.type, RODS_RECONNECT_T ) == 0 ) {
        rodsLog( LOG_NOTICE,
                 "readAndProcClientMsg: received reconnect msg from client" );
        /* call itself again. be careful */
        status = readAndProcClientMsg( rsComm, flags );
        return status;
    }
    else {
        rodsLog( LOG_NOTICE,
                 "agentMain: msg type %s not support by server",
                 myHeader.type );
        return USER_MSG_TYPE_NO_SUPPORT;
    }
}
コード例 #2
0
ファイル: sockComm.cpp プロジェクト: hurngchunlee/irods
// =-=-=-=-=-=-=-
//
irods::error readVersion(
    irods::network_object_ptr _ptr,
    version_t**         _version ) {
    // =-=-=-=-=-=-=-
    // init timval struct for header call
    struct timeval tv;
    tv.tv_sec = READ_VERSION_TOUT_SEC;
    tv.tv_usec = 0;

    // =-=-=-=-=-=-=-
    // call interface to read message header
    msgHeader_t myHeader;
    irods::error ret = readMsgHeader( _ptr, &myHeader, &tv );
    if ( !ret.ok() ) {
        return PASS( ret );
    }

    // =-=-=-=-=-=-=-
    // call interface to read message body
    bytesBuf_t inputStructBBuf, bsBBuf, errorBBuf;
    memset( &bsBBuf, 0, sizeof( bytesBuf_t ) );
    ret = readMsgBody( _ptr, &myHeader, &inputStructBBuf, &bsBBuf,
                       &errorBBuf, XML_PROT, NULL );
    if ( !ret.ok() ) {
        return PASS( ret );
    }

    // =-=-=-=-=-=-=-
    // basic error checking of message type
    if ( strcmp( myHeader.type, RODS_VERSION_T ) != 0 ) {
        if ( inputStructBBuf.buf != NULL ) {
            free( inputStructBBuf.buf );
        }
        if ( bsBBuf.buf != NULL ) {
            free( bsBBuf.buf );
        }
        if ( errorBBuf.buf != NULL ) {
            free( errorBBuf.buf );
        }
        std::stringstream msg;
        msg << "wrong msg type ["
            << myHeader.type
            << " expected ["
            << RODS_VERSION_T
            << "]";
        return ERROR( SYS_HEADER_TYPE_LEN_ERR, msg.str() );
    }

    // =-=-=-=-=-=-=-
    // check length of byte stream buffer, should be 0
    if ( myHeader.bsLen != 0 ) {
        if ( bsBBuf.buf != NULL ) {
            free( bsBBuf.buf );
        }
        rodsLog( LOG_NOTICE, "readVersion: myHeader.bsLen = %d is not 0",
                 myHeader.bsLen );
    }

    // =-=-=-=-=-=-=-
    // check length of error buffer, should be 0
    if ( myHeader.errorLen != 0 ) {
        if ( errorBBuf.buf != NULL ) {
            free( errorBBuf.buf );
        }
        rodsLog( LOG_NOTICE, "readVersion: myHeader.errorLen = %d is not 0",
                 myHeader.errorLen );
    }

    // =-=-=-=-=-=-=-
    // bounds check message size
    if ( myHeader.msgLen > ( int ) sizeof( version_t ) * 2 || myHeader.msgLen <= 0 ) {
        if ( inputStructBBuf.buf != NULL ) {
            free( inputStructBBuf.buf );
        }
        std::stringstream msg;
        msg << "header length is not within bounds: "
            << myHeader.msgLen;
        return ERROR( SYS_HEADER_READ_LEN_ERR, msg.str() );
    }

    // =-=-=-=-=-=-=-
    // unpack the message, always use XML for this message type
    int status = unpackStruct(
                     inputStructBBuf.buf,
                     ( void** )( _version ),
                     "Version_PI",
                     RodsPackTable,
                     XML_PROT );
    free( inputStructBBuf.buf );
    if ( status < 0 ) {
        rodsLogError( LOG_NOTICE, status,
                      "readVersion:unpackStruct error. status = %d",
                      status );
    }

    return CODE( status );

} // readVersion
コード例 #3
0
int
readAndProcApiReply( rcComm_t *conn, int apiInx, void **outStruct,
                     bytesBuf_t *outBsBBuf ) {
    int status = 0;
    msgHeader_t myHeader;
    /* bytesBuf_t outStructBBuf, errorBBuf, myOutBsBBuf; */
    bytesBuf_t outStructBBuf, errorBBuf;

    cliChkReconnAtReadStart( conn );

    memset( &outStructBBuf, 0, sizeof( bytesBuf_t ) );
    memset( &outStructBBuf, 0, sizeof( bytesBuf_t ) );
    /* memset (&myOutBsBBuf, 0, sizeof (bytesBuf_t)); */

    /* some sanity check */

    irods::api_entry_table& RcApiTable = irods::get_client_api_table();
    if ( RcApiTable[apiInx]->outPackInstruct != NULL && outStruct == NULL ) {
        rodsLog( LOG_ERROR,
                 "readAndProcApiReply: outStruct error for A apiNumber %d",
                 RcApiTable[apiInx]->apiNumber );
        cliChkReconnAtReadEnd( conn );
        return ( USER_API_INPUT_ERR );
    }

    if ( RcApiTable[apiInx]->outBsFlag > 0 && outBsBBuf == NULL ) {
        rodsLog( LOG_ERROR,
                 "readAndProcApiReply: outBsBBuf error for B apiNumber %d",
                 RcApiTable[apiInx]->apiNumber );
        cliChkReconnAtReadEnd( conn );
        return ( USER_API_INPUT_ERR );
    }

    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 = readMsgHeader( net_obj, &myHeader, NULL );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        if ( conn->svrVersion != NULL && conn->svrVersion->reconnPort > 0 ) {
            int savedStatus = ret.code();
            /* try again. the socket might have changed */
            conn->thread_ctx->lock->lock();
            rodsLog( LOG_DEBUG,
                     "readAndProcClientMsg:svrSwitchConnect.cliState = %d,agState=%d",
                     conn->clientState, conn->agentState );
            cliSwitchConnect( conn );
            conn->thread_ctx->lock->unlock();
            irods::error ret = readMsgHeader( net_obj, &myHeader, NULL );

            if ( !ret.ok() ) {
                cliChkReconnAtReadEnd( conn );
                return ( savedStatus );
            }
        }
        else {
            cliChkReconnAtReadEnd( conn );
            return ( ret.code() );
        }

    } // if !ret.ok

    ret = readMsgBody( net_obj, &myHeader, &outStructBBuf, outBsBBuf,
                       &errorBBuf, conn->irodsProt, NULL );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        cliChkReconnAtReadEnd( conn );
        return ( status );
    } // if !ret.ok

    cliChkReconnAtReadEnd( conn );

    if ( strcmp( myHeader.type, RODS_API_REPLY_T ) == 0 ) {
        status = procApiReply( conn, apiInx, outStruct, outBsBBuf,
                               &myHeader, &outStructBBuf, NULL, &errorBBuf );
    }

    clearBBuf( &outStructBBuf );
    /* clearBBuf (&myOutBsBBuf); */
    clearBBuf( &errorBBuf );

    return ( status );
}
コード例 #4
0
ファイル: sockComm.cpp プロジェクト: hurngchunlee/irods
// =-=-=-=-=-=-=-
//
irods::error readReconMsg(
    irods::network_object_ptr _ptr,
    reconnMsg_t**       _msg ) {
    int status;
    msgHeader_t myHeader;
    bytesBuf_t inputStructBBuf, bsBBuf, errorBBuf;
    // =-=-=-=-=-=-=-
    //
    irods::error ret = readMsgHeader( _ptr, &myHeader, NULL );
    if ( !ret.ok() ) {
        return PASSMSG( "read msg header error", ret );
    }

    memset( &bsBBuf, 0, sizeof( bytesBuf_t ) );
    ret = readMsgBody(
              _ptr,
              &myHeader,
              &inputStructBBuf,
              &bsBBuf,
              &errorBBuf,
              XML_PROT,
              NULL );
    if ( !ret.ok() ) {
        return PASS( ret );
    }

    /* some sanity check */

    if ( strcmp( myHeader.type, RODS_RECONNECT_T ) != 0 ) {
        if ( inputStructBBuf.buf != NULL ) {
            free( inputStructBBuf.buf );
        }
        if ( bsBBuf.buf != NULL ) {
            free( bsBBuf.buf );
        }
        if ( errorBBuf.buf != NULL ) {
            free( errorBBuf.buf );
        }
        std::stringstream msg;
        msg << "wrong msg type ["
            << myHeader.type
            << "] expected ["
            << RODS_CONNECT_T
            << "]";
        return ERROR( SYS_HEADER_TYPE_LEN_ERR, msg.str() );
    }

    if ( myHeader.bsLen != 0 ) {
        if ( bsBBuf.buf != NULL ) {
            free( bsBBuf.buf );
        }
        rodsLog( LOG_NOTICE, "readReconMsg: myHeader.bsLen = %d is not 0",
                 myHeader.bsLen );
    }

    if ( myHeader.errorLen != 0 ) {
        if ( errorBBuf.buf != NULL ) {
            free( errorBBuf.buf );
        }
        rodsLog( LOG_NOTICE,
                 "readReconMsg: myHeader.errorLen = %d is not 0",
                 myHeader.errorLen );
    }

    if ( myHeader.msgLen <= 0 ) {
        if ( inputStructBBuf.buf != NULL ) {
            free( inputStructBBuf.buf );
        }
        rodsLog( LOG_NOTICE,
                 "readReconMsg: problem with myHeader.msgLen = %d",
                 myHeader.msgLen );
        std::stringstream msg;
        msg << "message length is invalid: "
            << myHeader.msgLen;
        return ERROR( SYS_HEADER_READ_LEN_ERR, msg.str() );
    }

    /* always use XML_PROT for the startup pack */
    status = unpackStruct(
                 inputStructBBuf.buf,
                 ( void** )( _msg ),
                 "ReconnMsg_PI",
                 RodsPackTable,
                 XML_PROT );
    clearBBuf( &inputStructBBuf );
    if ( status < 0 ) {
        rodsLogError( LOG_NOTICE,  status,
                      "readReconMsg:unpackStruct error. status = %d",
                      status );
    }

    return CODE( status );
}
コード例 #5
0
/// =-=-=-=-=-=-=-
/// @brief function which sends the negotiation message
    error read_client_server_negotiation_message(
        irods::network_object_ptr      _ptr,
        boost::shared_ptr< cs_neg_t >&  _cs_neg_msg ) {
        // =-=-=-=-=-=-=-
        // read the message header
        struct timeval tv;
        tv.tv_sec = READ_VERSION_TOUT_SEC;
        tv.tv_usec = 0;

        msgHeader_t msg_header;
        irods::error ret = readMsgHeader( _ptr, &msg_header, &tv );
        if ( !ret.ok() ) {
            return PASSMSG( "read message header failed", ret );
        }

        // =-=-=-=-=-=-=-
        // read the message body
        bytesBuf_t struct_buf, data_buf, error_buf;
        memset( &data_buf, 0, sizeof( bytesBuf_t ) );
        ret = readMsgBody(
                  _ptr,
                  &msg_header,
                  &struct_buf,
                  &data_buf,
                  &error_buf,
                  XML_PROT, 0 );
        if ( !ret.ok() ) {
            return PASS( ret );

        }

        // =-=-=-=-=-=-=-
        // check that we did in fact get the right type of message
        if ( strcmp( msg_header.type, RODS_CS_NEG_T ) != 0 ) {
            // =-=-=-=-=-=-=-
            // trap potential case where server does not support
            // advanced negotiation.  a version msg would be sent
            // back instead.
            if ( strcmp( msg_header.type, RODS_VERSION_T ) == 0 ) {
                // =-=-=-=-=-=-=-
                // unpack the version struct to check the status
                version_t* version = 0;
                int status = unpackStruct(
                                 struct_buf.buf,
                                 ( void ** )( static_cast<void *>( &version ) ),
                                 "Version_PI",
                                 RodsPackTable,
                                 XML_PROT );

                if ( struct_buf.buf ) {
                    free( struct_buf.buf );
                }
                if ( data_buf.buf ) {
                    free( data_buf.buf );
                }
                if ( error_buf.buf ) {
                    free( error_buf.buf );
                }

                if ( status < 0 ) {
                    rodsLog( LOG_ERROR, "read_client_server_negotiation_message :: unpackStruct FAILED" );
                    return ERROR( status, "unpackStruct failed" );

                }

                if ( version->status < 0 ) {
                    rodsLog( LOG_ERROR, "read_client_server_negotiation_message :: received error message %d", version->status );
                    return ERROR( version->status, "negotiation failed" );

                }
                else {
                    // =-=-=-=-=-=-=-
                    // if no negoation is allowed then provide a readable
                    // error for the client
                    std::stringstream msg;
                    msg << "received [" << msg_header.type << "] ";
                    msg << "but expected [" << RODS_CS_NEG_T << "]\n\n";
                    msg << "\t*** Advanced negotiation is enabled in this iRODS environment   ***\n";
                    msg << "\t*** which is most likely not supported by the server.           ***\n";
                    msg << "\t*** Comment out irodsClientServerNegotiation in the irodsEnv    ***\n";
                    msg << "\t*** file to disable.                                            ***\n";
                    return ERROR( ADVANCED_NEGOTIATION_NOT_SUPPORTED, msg.str() );
                }

            }
            else {
                // =-=-=-=-=-=-=-
                // something entirely unexpected happened
                std::stringstream msg;
                msg << "wrong message type [" << msg_header.type << "] ";
                msg << "expected [" << RODS_CS_NEG_T << "]";
                return ERROR( SYS_HEADER_TYPE_LEN_ERR, msg.str() );
            }
        }

        // =-=-=-=-=-=-=-
        // check that we did not get any data with the message
        if ( msg_header.bsLen != 0 ) {
            if ( data_buf.buf != NULL ) {
                free( data_buf.buf );
            }
            rodsLog( LOG_NOTICE,
                     "read_client_server_negotiation_message: msg_header.bsLen = %d is not 0",
                     msg_header.bsLen );
        }

        // =-=-=-=-=-=-=-
        // check that we did not get anything in the error buffer
        if ( msg_header.errorLen != 0 ) {
            if ( error_buf.buf ) {
                free( error_buf.buf );
            }
            rodsLog( LOG_NOTICE,
                     "read_client_server_negotiation_message: msg_header.errorLen = %d is not 0",
                     msg_header.errorLen );
        }

        // =-=-=-=-=-=-=-
        // check that we did get an appropriately sized message
        if ( msg_header.msgLen > ( int ) sizeof( irods::cs_neg_t ) * 2 ||
                msg_header.msgLen <= 0 ) {
            if ( struct_buf.buf != NULL ) {
                free( struct_buf.buf );
            }
            std::stringstream msg;
            msg << "message length is invalid: " << msg_header.msgLen << " vs " << sizeof( irods::cs_neg_t );
            return ERROR( SYS_HEADER_READ_LEN_ERR, msg.str() );
        }

        // =-=-=-=-=-=-=-
        // do an unpack into our out variable using the xml protocol
        cs_neg_t* tmp_cs_neg = 0;
        int status = unpackStruct( struct_buf.buf,
                                   ( void ** )( static_cast<void *>( &tmp_cs_neg ) ),
                                   "CS_NEG_PI",
                                   RodsPackTable,
                                   XML_PROT );
        free( struct_buf.buf );
        if ( status < 0 ) {
            rodsLog( LOG_ERROR, "read_client_server_negotiation_message :: unpackStruct FAILED" );
            return ERROR( status, "unpackStruct failed" );

        }

        _cs_neg_msg.reset( tmp_cs_neg, free );

        // =-=-=-=-=-=-=-
        // win!!!111one
        return SUCCESS();

    } // read_client_server_negotiation_message