Esempio n. 1
0
    void operator()() const {
        DBClientConnection dest;
        string errmsg;
        while (!dest.connect(mongoBridgeGlobalParams.destUri, errmsg))
            sleepmillis( 500 );
        Message m;
        while( 1 ) {
            try {
                m.reset();
                if ( !mp_.recv( m ) ) {
                    cout << "end connection " << mp_.psock->remoteString() << endl;
                    mp_.shutdown();
                    break;
                }
                sleepmillis(mongoBridgeGlobalParams.delay);

                int oldId = m.header()->id;
                if ( m.operation() == dbQuery || m.operation() == dbMsg || m.operation() == dbGetMore ) {
                    bool exhaust = false;
                    if ( m.operation() == dbQuery ) {
                        DbMessage d( m );
                        QueryMessage q( d );
                        exhaust = q.queryOptions & QueryOption_Exhaust;
                    }
                    Message response;
                    dest.port().call( m, response );

                    // nothing to reply with?
                    if ( response.empty() ) cleanup(0);

                    mp_.reply( m, response, oldId );
                    while ( exhaust ) {
                        MsgData *header = response.header();
                        QueryResult *qr = (QueryResult *) header;
                        if ( qr->cursorId ) {
                            response.reset();
                            dest.port().recv( response );
                            mp_.reply( m, response ); // m argument is ignored anyway
                        }
                        else {
                            exhaust = false;
                        }
                    }
                }
                else {
                    dest.port().say( m, oldId );
                }
            }
            catch ( ... ) {
                log() << "caught exception in Forwarder, continuing" << endl;
            }
        }
    }
Esempio n. 2
0
    void operator()() const {
        DBClientConnection dest;
        string errmsg;
        while( !dest.connect( destUri, errmsg ) )
            sleepmillis( 500 );
        Message m;
        while( 1 ) {
            m.reset();
            if ( !mp_.recv( m ) ) {
                cout << "end connection " << mp_.farEnd.toString() << endl;
                mp_.shutdown();
                break;
            }

            int oldId = m.data->id;
            if ( m.data->operation() == dbQuery || m.data->operation() == dbMsg || m.data->operation() == dbGetMore ) {
                Message response;
                dest.port().call( m, response );
                mp_.reply( m, response, oldId );
            } else {
                dest.port().say( m, oldId );
            }
        }
    }
Esempio n. 3
0
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
	
	const struct sniff_ip* ip = (struct sniff_ip*)(packet + captureHeaderSize);
	int size_ip = IP_HL(ip)*4;
	if ( size_ip < 20 ){
		cerr << "*** Invalid IP header length: " << size_ip << " bytes" << endl;
		return;
	}
    
    assert( ip->ip_p == IPPROTO_TCP );

	const struct sniff_tcp* tcp = (struct sniff_tcp*)(packet + captureHeaderSize + size_ip);
	int size_tcp = TH_OFF(tcp)*4;
	if (size_tcp < 20){
		cerr << "*** Invalid TCP header length: " << size_tcp << " bytes" << endl;
		return;
	}

    if ( ! ( serverPorts.count( ntohs( tcp->th_sport ) ) ||
             serverPorts.count( ntohs( tcp->th_dport ) ) ) ){
        return;
    }
	
	const u_char * payload = (const u_char*)(packet + captureHeaderSize + size_ip + size_tcp);

	unsigned totalSize = ntohs(ip->ip_len);
    assert( totalSize <= header->caplen );

    int size_payload = totalSize - (size_ip + size_tcp);
	if (size_payload <= 0 )
        return;
        
    Connection c;
    c.srcAddr = ip->ip_src;
    c.srcPort = tcp->th_sport;
    c.dstAddr = ip->ip_dst;
    c.dstPort = tcp->th_dport;
    
    if ( seen[ c ] ) {
        if ( expectedSeq[ c ] != ntohl( tcp->th_seq ) ) {
            cerr << "Warning: sequence # mismatch, there may be dropped packets" << endl;
        }
    } else {
        seen[ c ] = true;
    }
    
    expectedSeq[ c ] = ntohl( tcp->th_seq ) + size_payload;
    
    Message m;
    
    if ( bytesRemainingInMessage[ c ] == 0 ) {
        m.setData( (MsgData*)payload , false );
        if ( !m.data->valid() ) {
            cerr << "Invalid message start, skipping packet." << endl;
            return;
        }
        if ( size_payload > m.data->len ) {
            cerr << "Multiple messages in packet, skipping packet." << endl;
            return;
        }
        if ( size_payload < m.data->len ) {
            bytesRemainingInMessage[ c ] = m.data->len - size_payload;
            messageBuilder[ c ].reset( new BufBuilder() );
            messageBuilder[ c ]->append( (void*)payload, size_payload );
            return;
        }
    } else {
        bytesRemainingInMessage[ c ] -= size_payload;
        messageBuilder[ c ]->append( (void*)payload, size_payload );
        if ( bytesRemainingInMessage[ c ] < 0 ) {
            cerr << "Received too many bytes to complete message, resetting buffer" << endl;
            bytesRemainingInMessage[ c ] = 0;
            messageBuilder[ c ].reset();
            return;
        }
        if ( bytesRemainingInMessage[ c ] > 0 )
            return;
        m.setData( (MsgData*)messageBuilder[ c ]->buf(), true );
        messageBuilder[ c ]->decouple();
        messageBuilder[ c ].reset();
    }

    DbMessage d( m );
    
    cout << inet_ntoa(ip->ip_src) << ":" << ntohs( tcp->th_sport ) 
         << ( serverPorts.count( ntohs( tcp->th_dport ) ) ? "  -->> " : "  <<--  " )
         << inet_ntoa(ip->ip_dst) << ":" << ntohs( tcp->th_dport ) 
         << " " << d.getns() 
         << "  " << m.data->len << " bytes "
         << m.data->id;
    
    if ( m.data->operation() == mongo::opReply )
        cout << " - " << m.data->responseTo;
    cout << endl;

    switch( m.data->operation() ){
    case mongo::opReply:{
        mongo::QueryResult* r = (mongo::QueryResult*)m.data;
        cout << "\treply" << " n:" << r->nReturned << " cursorId: " << r->cursorId << endl;
        if ( r->nReturned ){
            mongo::BSONObj o( r->data() , 0 );
            cout << "\t" << o << endl;
        }
        break;
    }
    case mongo::dbQuery:{
        mongo::QueryMessage q(d);
        cout << "\tquery: " << q.query << endl;
        break;
    }
    case mongo::dbUpdate:{
        int flags = d.pullInt();
        BSONObj q = d.nextJsObj();
        BSONObj o = d.nextJsObj();
        cout << "\tupdate  flags:" << flags << " q:" << q << " o:" << o << endl;
        break;
    }
    case mongo::dbInsert:{
        cout << "\tinsert: " << d.nextJsObj() << endl;
        while ( d.moreJSObjs() )
            cout << "\t\t" << d.nextJsObj() << endl;
        break;
    }
    case mongo::dbGetMore:{
        int nToReturn = d.pullInt();
        long long cursorId = d.pullInt64();
        cout << "\tgetMore nToReturn: " << nToReturn << " cursorId: " << cursorId << endl;
        break;        
    }
    case mongo::dbDelete:{
        int flags = d.pullInt();
        BSONObj q = d.nextJsObj();
        cout << "\tdelete flags: " << flags << " q: " << q << endl;
        break;                
    }
    case mongo::dbKillCursors:{
        int *x = (int *) m.data->_data;
        x++; // reserved
        int n = *x;
        cout << "\tkillCursors n: " << n << endl;
        break;
    }
    default:
        cerr << "*** CANNOT HANDLE TYPE: " << m.data->operation() << endl;
    }    
    
    if ( !forwardAddress.empty() ) {
        if ( m.data->operation() != mongo::opReply ) {
            DBClientConnection *conn = forwarder[ c ];
            if ( !conn ) {
                // These won't get freed on error, oh well hopefully we'll just
                // abort in that case anyway.
                conn = new DBClientConnection( true );
                conn->connect( forwardAddress );
                forwarder[ c ] = conn;
            }
            if ( m.data->operation() == mongo::dbQuery || m.data->operation() == mongo::dbGetMore ) {
                if ( m.data->operation() == mongo::dbGetMore ) {
                    DbMessage d( m );
                    d.pullInt();
                    long long &cId = d.pullInt64();
                    cId = mapCursor[ c ][ cId ];
                }
                Message response;
                conn->port().call( m, response );
                QueryResult *qr = (QueryResult *) response.data;
                if ( !( qr->resultFlags() & QueryResult::ResultFlag_CursorNotFound ) ) {
                    if ( qr->cursorId != 0 ) {
                        lastCursor[ c ] = qr->cursorId;
                        return;
                    }
                }
                lastCursor[ c ] = 0;
            } else {
                conn->port().say( m );
            }
        } else {
            Connection r = c.reverse();
            long long myCursor = lastCursor[ r ];
            QueryResult *qr = (QueryResult *) m.data;
            long long yourCursor = qr->cursorId;
            if ( ( qr->resultFlags() & QueryResult::ResultFlag_CursorNotFound ) )
                yourCursor = 0;
            if ( myCursor && !yourCursor )
                cerr << "Expected valid cursor in sniffed response, found none" << endl;
            if ( !myCursor && yourCursor )
                cerr << "Sniffed valid cursor when none expected" << endl;
            if ( myCursor && yourCursor ) {
                mapCursor[ r ][ qr->cursorId ] = lastCursor[ r ];
                lastCursor[ r ] = 0;
            }
        }
    }
}
Esempio n. 4
0
    void operator()() const {
        DBClientConnection dest;
        string errmsg;

        Timer connectTimer;
        while (!dest.connect(HostAndPort(mongoBridgeGlobalParams.destUri), errmsg)) {
            // If we can't connect for the configured timeout, give up
            //
            if (connectTimer.seconds() >= mongoBridgeGlobalParams.connectTimeoutSec) {
                cout << "Unable to establish connection from " << mp_.psock->remoteString()
                     << " to " << mongoBridgeGlobalParams.destUri
                     << " after " << connectTimer.seconds() << " seconds. Giving up." << endl;
                mp_.shutdown();
                return;
            }

            sleepmillis(500);
        }

        Message m;
        while( 1 ) {
            try {
                m.reset();
                if ( !mp_.recv( m ) ) {
                    cout << "end connection " << mp_.psock->remoteString() << endl;
                    mp_.shutdown();
                    break;
                }
                sleepmillis(mongoBridgeGlobalParams.delay);

                int oldId = m.header()->id;
                if ( m.operation() == dbQuery || m.operation() == dbMsg || m.operation() == dbGetMore ) {
                    bool exhaust = false;
                    if ( m.operation() == dbQuery ) {
                        DbMessage d( m );
                        QueryMessage q( d );
                        exhaust = q.queryOptions & QueryOption_Exhaust;
                    }
                    Message response;
                    dest.port().call( m, response );

                    // nothing to reply with?
                    if ( response.empty() ) cleanup(0);

                    mp_.reply( m, response, oldId );
                    while ( exhaust ) {
                        MsgData *header = response.header();
                        QueryResult *qr = (QueryResult *) header;
                        if ( qr->cursorId ) {
                            response.reset();
                            dest.port().recv( response );
                            mp_.reply( m, response ); // m argument is ignored anyway
                        }
                        else {
                            exhaust = false;
                        }
                    }
                }
                else {
                    dest.port().say( m, oldId );
                }
            }
            catch ( ... ) {
                log() << "caught exception in Forwarder, continuing" << endl;
            }
        }
    }