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