Exemplo n.º 1
0
void
CTCPSocket::connect(const CNetworkAddress& addr)
{
	{
		CLock lock(&m_mutex);

		// fail on attempts to reconnect
		if (m_socket == NULL || m_connected) {
			sendConnectionFailedEvent("busy");
			return;
		}

		try {
			if (ARCH->connectSocket(m_socket, addr.getAddress())) {
				sendEvent(getConnectedEvent());
				onConnected();
			}
			else {
				// connection is in progress
				m_writable = true;
			}
		}
		catch (XArchNetwork& e) {
			throw XSocketConnect(e.what());
		}
	}
	setJob(newJob());
}
Exemplo n.º 2
0
void
CClient::connect()
{
	if (m_stream != NULL) {
		return;
	}
	if (m_suspended) {
		m_connectOnResume = true;
		return;
	}

	try {
		// resolve the server hostname.  do this every time we connect
		// in case we couldn't resolve the address earlier or the address
		// has changed (which can happen frequently if this is a laptop
		// being shuttled between various networks).  patch by Brent
		// Priddy.
		m_serverAddress.resolve();
		
		// m_serverAddress will be null if the hostname address is not reolved
		if (m_serverAddress.getAddress() != NULL) {
		  // to help users troubleshoot, show server host name (issue: 60)
		  LOG((CLOG_NOTE "connecting to '%s': %s:%i", 
		  m_serverAddress.getHostname().c_str(),
		  ARCH->addrToString(m_serverAddress.getAddress()).c_str(),
		  m_serverAddress.getPort()));
		}

		// create the socket
		IDataSocket* socket = m_socketFactory->create();

		// filter socket messages, including a packetizing filter
		m_stream = socket;
		if (m_streamFilterFactory != NULL) {
			m_stream = m_streamFilterFactory->create(m_stream, true);
		}
		m_stream = new CPacketStreamFilter(m_events, m_stream, true);

		if (m_crypto.m_mode != kDisabled) {
			m_cryptoStream = new CCryptoStream(
				m_events, m_stream, m_crypto, true);
			m_stream = m_cryptoStream;
		}

		// connect
		LOG((CLOG_DEBUG1 "connecting to server"));
		setupConnecting();
		setupTimer();
		socket->connect(m_serverAddress);
	}
	catch (XBase& e) {
		cleanupTimer();
		cleanupConnecting();
		delete m_stream;
		m_stream = NULL;
		LOG((CLOG_DEBUG1 "connection failed"));
		sendConnectionFailedEvent(e.what());
		return;
	}
}
Exemplo n.º 3
0
void
Client::handleConnectTimeout(const Event&, void*)
{
	cleanupTimer();
	cleanupConnecting();
	cleanupConnection();
	cleanupStream();
	LOG((CLOG_DEBUG1 "connection timed out"));
	sendConnectionFailedEvent("Timed out");
}
Exemplo n.º 4
0
void
CClient::handleConnectTimeout(const CEvent&, void*)
{
	cleanupTimer();
	cleanupConnecting();
	cleanupConnection();
	delete m_stream;
	m_stream = NULL;
	LOG((CLOG_DEBUG1 "connection timed out"));
	sendConnectionFailedEvent("Timed out");
}
Exemplo n.º 5
0
void
Client::handleHello(const Event&, void*)
{
	SInt16 major, minor;
	if (!ProtocolUtil::readf(m_stream, kMsgHello, &major, &minor)) {
		sendConnectionFailedEvent("Protocol error from server, check encryption settings");
		cleanupTimer();
		cleanupConnection();
		return;
	}

	// check versions
	LOG((CLOG_DEBUG1 "got hello version %d.%d", major, minor));
	if (major < kProtocolMajorVersion ||
		(major == kProtocolMajorVersion && minor < kProtocolMinorVersion)) {
		sendConnectionFailedEvent(XIncompatibleClient(major, minor).what());
		cleanupTimer();
		cleanupConnection();
		return;
	}

	// say hello back
	LOG((CLOG_DEBUG1 "say hello version %d.%d", kProtocolMajorVersion, kProtocolMinorVersion));
	ProtocolUtil::writef(m_stream, kMsgHelloBack,
							kProtocolMajorVersion,
							kProtocolMinorVersion, &m_name);

	// now connected but waiting to complete handshake
	setupScreen();
	cleanupTimer();

	// make sure we process any remaining messages later.  we won't
	// receive another event for already pending messages so we fake
	// one.
	if (m_stream->isReady()) {
		m_events->addEvent(Event(m_events->forIStream().inputReady(),
							m_stream->getEventTarget()));
	}
}
Exemplo n.º 6
0
void
Client::handleConnectionFailed(const Event& event, void*)
{
	IDataSocket::ConnectionFailedInfo* info =
		reinterpret_cast<IDataSocket::ConnectionFailedInfo*>(event.getData());

	cleanupTimer();
	cleanupConnecting();
	cleanupStream();
	LOG((CLOG_DEBUG1 "connection failed"));
	sendConnectionFailedEvent(info->m_what.c_str());
	delete info;
}
Exemplo n.º 7
0
void
Client::disconnect(const char* msg)
{
	m_connectOnResume = false;
	cleanupTimer();
	cleanupScreen();
	cleanupConnecting();
	cleanupConnection();
	if (msg != NULL) {
		sendConnectionFailedEvent(msg);
	}
	else {
		sendEvent(m_events->forClient().disconnected(), NULL);
	}
}
Exemplo n.º 8
0
void
CClient::connect()
{
	if (m_stream != NULL) {
		return;
	}
	if (m_suspended) {
		m_connectOnResume = true;
		return;
	}

	try {
		// resolve the server hostname.  do this every time we connect
		// in case we couldn't resolve the address earlier or the address
		// has changed (which can happen frequently if this is a laptop
		// being shuttled between various networks).  patch by Brent
		// Priddy.
		m_serverAddress.resolve();

		// create the socket
		IDataSocket* socket = m_socketFactory->create();

		// filter socket messages, including a packetizing filter
		m_stream = socket;
		if (m_streamFilterFactory != NULL) {
			m_stream = m_streamFilterFactory->create(m_stream, true);
		}
		m_stream = new CPacketStreamFilter(m_stream, true);

		// connect
		LOG((CLOG_DEBUG1 "connecting to server"));
		setupConnecting();
		setupTimer();
		socket->connect(m_serverAddress);
	}
	catch (XBase& e) {
		cleanupTimer();
		cleanupConnecting();
		delete m_stream;
		m_stream = NULL;
		LOG((CLOG_DEBUG1 "connection failed"));
		sendConnectionFailedEvent(e.what());
		return;
	}
}
Exemplo n.º 9
0
ISocketMultiplexerJob*
CTCPSocket::serviceConnecting(ISocketMultiplexerJob* job,
				bool, bool write, bool error)
{
	CLock lock(&m_mutex);

	// should only check for errors if error is true but checking a new
	// socket (and a socket that's connecting should be new) for errors
	// should be safe and Mac OS X appears to have a bug where a
	// non-blocking stream socket that fails to connect immediately is
	// reported by select as being writable (i.e. connected) even when
	// the connection has failed.  this is easily demonstrated on OS X
	// 10.3.4 by starting a synergy client and telling to connect to
	// another system that's not running a synergy server.  it will
	// claim to have connected then quickly disconnect (i guess because
	// read returns 0 bytes).  unfortunately, synergy attempts to
	// reconnect immediately, the process repeats and we end up
	// spinning the CPU.  luckily, OS X does set SO_ERROR on the
	// socket correctly when the connection has failed so checking for
	// errors works.  (curiously, sometimes OS X doesn't report
	// connection refused.  when that happens it at least doesn't
	// report the socket as being writable so synergy is able to time
	// out the attempt.)
	if (error || true) {
		try {
			// connection may have failed or succeeded
			ARCH->throwErrorOnSocket(m_socket);
		}
		catch (XArchNetwork& e) {
			sendConnectionFailedEvent(e.what().c_str());
			onDisconnected();
			return newJob();
		}
	}

	if (write) {
		sendEvent(getConnectedEvent());
		onConnected();
		return newJob();
	}

	return job;
}