void executeCommandPasv(ClientThreadResource * res , int * result) {
    char * m;
    int cantRetries = 0;
    char * port = calculatePort(getServerDataPort() , res->heapHandler);

    res->dataSocket = openServerSocket(getServerAddress() , port);
    while( (res->dataSocket == INVALID_SOCKET)
            && (cantRetries < getMaxRetriesFindingDataPort())) {
        port = calculatePort(port , res->heapHandler);
        res->dataSocket = openServerSocket(getServerAddress() , port);
        cantRetries++;
    }

    validateAndCloseDataConnection(res);
    res->mode = FTP_DATA_MODE_PASIVE;

    m = concat(res->heapHandler , 4 ,
               "227 (" , encodeHostAndPort(getServerAddress() , port , res->heapHandler),
               ")" , CHARACTER_CRLF);

    sendMessage(res->controlSocket , m , &result);
}
Exemplo n.º 2
0
void uplink(void){

	/* Transport endpoint */
	if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
		perror("<LOG socket_s.c> Socket call failed <end>");
		exit(EXIT_FAILURE);
	}

	// Set SO_REUSEADDR on a socket to true (1).
	// This will help us if the server unexpectedly crashes and we need to
	// restart it. If we do not use this option, we must remove manually the
	// /tmp/socket_server file. This will prevent bind call failures

	int optval = 1;

	if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(int)) == -1) {
	    perror("setsockopt");
	    exit(1);
	}

	/* FROM HAVILAND (for understanding purposes):

		-1- "bind" the server  address to the end point

		-2- start listening for incoming connections

		-3- loop
				accept incomming connections
				spawn a chld to deal with the connection (thread!)
				if child
					send an receive information with the client
	*/

	struct sockaddr_in * addr_server = getServerAddress();
	
    // -1- "Bind" the server  address to the end point
	if( (bind( sockfd, (struct sockaddr *) addr_server, SOCKET_SIZE)) == -1 ){
		perror("<LOG socket_s.c> Bind call failed in upLink() <end>");
		exit(EXIT_FAILURE);
	}

	/* Save the socket default flags */
	socket_flags = fcntl(sockfd,F_GETFL,0);

	sockets_hmap = hashmap_new(10); // Initialize hashmap with space for 10 clients
}
Exemplo n.º 3
0
    void ReplicaSetMonitor::_check() {

        bool triedQuickCheck = false;

        LOG(1) <<  "_check : " << getServerAddress() << endl;

        for ( int retry = 0; retry < 2; retry++ ) {
            for ( unsigned i=0; i<_nodes.size(); i++ ) {
                DBClientConnection * c;
                {
                    scoped_lock lk( _lock );
                    c = _nodes[i].conn;
                }

                string maybePrimary;
                if ( _checkConnection( c , maybePrimary , retry ) ) {
                    _master = i;
                    return;
                }

                if ( ! triedQuickCheck && maybePrimary.size() ) {
                    int x = _find( maybePrimary );
                    if ( x >= 0 ) {
                        triedQuickCheck = true;
                        string dummy;
                        DBClientConnection * testConn;
                        {
                            scoped_lock lk( _lock );
                            testConn = _nodes[x].conn;
                        }
                        if ( _checkConnection( testConn , dummy , false ) ) {
                            _master = x;
                            return;
                        }
                    }
                }

            }
            sleepsecs(1);
        }

    }
Exemplo n.º 4
0
    void ReplicaSetMonitor::_checkHosts( const BSONObj& hostList, bool& changed ) {
        BSONObjIterator hi(hostList);
        while ( hi.more() ) {
            string toCheck = hi.next().String();

            if ( _find( toCheck ) >= 0 )
                continue;

            HostAndPort h( toCheck );
            DBClientConnection * newConn = new DBClientConnection( true, 0, 5.0 );
            string temp;
            newConn->connect( h , temp );
            {
                scoped_lock lk( _lock );
                _nodes.push_back( Node( h , newConn ) );
            }
            log() << "updated set (" << _name << ") to: " << getServerAddress() << endl;
            changed = true;
        }
    }
Exemplo n.º 5
0
std::unique_ptr<DBClientBase> ConnectionString::connect(StringData applicationName,
                                                        std::string& errmsg,
                                                        double socketTimeout,
                                                        const MongoURI* uri) const {
    MongoURI newURI{};
    if (uri) {
        newURI = *uri;
    }

    switch (_type) {
        case MASTER: {
            for (const auto& server : _servers) {
                auto c = stdx::make_unique<DBClientConnection>(true, 0, newURI);

                c->setSoTimeout(socketTimeout);
                LOG(1) << "creating new connection to:" << server;
                if (!c->connect(server, applicationName, errmsg)) {
                    continue;
                }
                LOG(1) << "connected connection!";
                return std::move(c);
            }
            return nullptr;
        }

        case SET: {
            auto set = stdx::make_unique<DBClientReplicaSet>(
                _setName, _servers, applicationName, socketTimeout, std::move(newURI));
            if (!set->connect()) {
                errmsg = "connect failed to replica set ";
                errmsg += toString();
                return nullptr;
            }
            return std::move(set);
        }

        case CUSTOM: {
            // Lock in case other things are modifying this at the same time
            stdx::lock_guard<stdx::mutex> lk(_connectHookMutex);

            // Allow the replacement of connections with other connections - useful for testing.

            uassert(16335,
                    "custom connection to " + this->toString() +
                        " specified with no connection hook",
                    _connectHook);

            // Double-checked lock, since this will never be active during normal operation
            auto replacementConn = _connectHook->connect(*this, errmsg, socketTimeout);

            log() << "replacing connection to " << this->toString() << " with "
                  << (replacementConn ? replacementConn->getServerAddress() : "(empty)");

            return replacementConn;
        }

        case LOCAL:
        case INVALID:
            MONGO_UNREACHABLE;
    }

    MONGO_UNREACHABLE;
}
Exemplo n.º 6
0
    bool DBClientConnection::call( Message &toSend, Message &response, bool assertOk , string * actualServer ) {
        /* todo: this is very ugly messagingport::call returns an error code AND can throw
                 an exception.  we should make it return void and just throw an exception anytime
                 it fails
        */
        checkConnection();
        try {
            if ( !port().call(toSend, response) ) {
                _failed = true;
                if ( assertOk )
                    uasserted( 10278 , str::stream() << "dbclient error communicating with server: " << getServerAddress() );

                return false;
            }
        }
        catch( SocketException & ) {
            _failed = true;
            throw;
        }
        return true;
    }
Exemplo n.º 7
0
    /** query N objects from the database into an array.  makes sense mostly when you want a small number of results.  if a huge number, use 
        query() and iterate the cursor. 
     */
    void DBClientInterface::findN(vector<BSONObj>& out, const string& ns, Query query, int nToReturn, int nToSkip, const BSONObj *fieldsToReturn, int queryOptions) { 
        out.reserve(nToReturn);

        auto_ptr<DBClientCursor> c =
            this->query(ns, query, nToReturn, nToSkip, fieldsToReturn, queryOptions);

        uassert( 10276 ,  str::stream() << "DBClientBase::findN: transport error: " << getServerAddress() << " query: " << query.toString(), c.get() );

        if ( c->hasResultFlag( ResultFlag_ShardConfigStale ) )
            throw StaleConfigException( ns , "findN stale config" );

        for( int i = 0; i < nToReturn; i++ ) {
            if ( !c->more() )
                break;
            out.push_back( c->nextSafe().copy() );
        }
    }