Esempio n. 1
0
File: net.c Progetto: L3oV1nc3/VMGL
/**
 * Establish a connection with a server.
 * \param server  the server to connect to, in the form
 *                "protocol://servername:port" where the port specifier
 *                is optional and if the protocol is missing it is assumed
 *                to be "tcpip".
 * \param default_port  the port to connect to, if port not specified in the
 *                      server URL string.
 * \param mtu  desired maximum transmission unit size (in bytes)
 */
CRConnection *
crNetConnectToServer( const char *server, unsigned short default_port, int mtu)
{
	char hostname[4096], protocol[4096];
	unsigned short port;
	CRConnection *conn;

	crDebug( "In crNetConnectToServer( \"%s\", port=%d, mtu=%d )",
					 server, default_port, mtu );

	CRASSERT( cr_net.initialized );

	if (mtu < CR_MINIMUM_MTU)
	{
		crError( "You tried to connect to server \"%s\" with an mtu of %d, "
						 "but the minimum MTU is %d", server, mtu, CR_MINIMUM_MTU );
	}

	/* Tear the URL apart into relevant portions. */
	if ( !crParseURL( server, protocol, hostname, &port, default_port ) ) {
		 crError( "Malformed URL: \"%s\"", server );
	}

	crDebug( "Connecting to %s on port %d, with protocol %s",
					 hostname, port, protocol );

	conn = (CRConnection *) crCalloc( sizeof(*conn) );
	if (!conn)
		return NULL;

	/* init the non-zero fields */
	conn->type               = CR_NO_CONNECTION; /* we don't know yet */
	conn->recv_credits       = CR_INITIAL_RECV_CREDITS;
	conn->hostname           = crStrdup( hostname );
	conn->port               = port;
	conn->mtu                = mtu;
	conn->buffer_size        = mtu;
	conn->endianness         = crDetermineEndianness();

#ifdef CHROMIUM_THREADSAFE
	crInitMutex(&conn->messageList.lock);
	crInitCondition(&conn->messageList.nonEmpty);
#endif

	/* now, just dispatch to the appropriate protocol's initialization functions. */
	InitConnection(conn, protocol, mtu);

	if (!crNetConnect( conn ))
	{
		crDebug("crNetConnectToServer() failed, freeing the connection");
		crFree( conn );
		return NULL;
	}

	crDebug( "Done connecting to %s (swapping=%d)", server, conn->swap );
#ifndef NDEBUG
	crNetDumpConnectionInfo(conn);
#endif
	return conn;
}
Esempio n. 2
0
static void swapsyncConnect(void)
{
    char hostname[4096], protocol[4096];
    unsigned short port;

    crNetInit(NULL, NULL);

    if (!crParseURL( render_spu.swap_master_url, protocol, hostname,
                    &port, 9876))
        crError( "Bad URL: %s", render_spu.swap_master_url );

    if (render_spu.is_swap_master)
    {
        int a;

        render_spu.swap_conns = (CRConnection **)crAlloc(
                        render_spu.num_swap_clients*sizeof(CRConnection *));
        for (a=0; a<render_spu.num_swap_clients; a++)
        {
            render_spu.swap_conns[a] = crNetAcceptClient( protocol, hostname, port,
                                                        render_spu.swap_mtu, 1);
        }
    }
    else
    {
        render_spu.swap_conns = (CRConnection **)crAlloc(sizeof(CRConnection *));

        render_spu.swap_conns[0] = crNetConnectToServer(render_spu.swap_master_url,
                                    port, render_spu.swap_mtu, 1);
        if (!render_spu.swap_conns[0])
            crError("Failed connection");
    }
}
Esempio n. 3
0
/**
 * Accept a connection from a client.
 * \param protocol  the protocol to use (such as "tcpip" or "gm")
 * \param hostname  optional hostname of the expected client (may be NULL)
 * \param port  number of the port to accept on
 * \param mtu  maximum transmission unit
 * \param broker  either 1 or 0 to indicate if connection is brokered through
 *                the mothership
 * \return  new CRConnection object, or NULL
 */
CRConnection *
crNetAcceptClient( const char *protocol, const char *hostname,
									 unsigned short port, unsigned int mtu, int broker )
{
	CRConnection *conn;

	CRASSERT( cr_net.initialized );

	conn = (CRConnection *) crCalloc( sizeof( *conn ) );
	if (!conn)
		return NULL;

	/* init the non-zero fields */
	conn->type               = CR_NO_CONNECTION; /* we don't know yet */
	conn->recv_credits       = CR_INITIAL_RECV_CREDITS;
	conn->port               = port;
	conn->mtu                = mtu;
	conn->buffer_size        = mtu;
	conn->broker             = broker;
	conn->endianness         = crDetermineEndianness();
	conn->teac_id            = -1;
	conn->teac_rank          = -1;
	conn->tcscomm_id         = -1;
	conn->tcscomm_rank       = -1;

	/* now, just dispatch to the appropriate protocol's initialization functions. */
	crDebug("In crNetAcceptClient( protocol=\"%s\" port=%d mtu=%d )",
					protocol, (int) port, (int) mtu);

	/* special case */
	if ( !crStrncmp( protocol, "file", crStrlen( "file" ) ) ||
			 !crStrncmp( protocol, "swapfile", crStrlen( "swapfile" ) ) )
	{
		char filename[4096];
    char protocol_only[4096];

		cr_net.use_file++;
		if (!crParseURL(protocol, protocol_only, filename, NULL, 0))
		{
			crError( "Malformed URL: \"%s\"", protocol );
		}
		conn->hostname = crStrdup( filename );

    /* call the protocol-specific init routines */  // ktd (add)
    InitConnection(conn, protocol_only, mtu);       // ktd (add)
	}
	else {
  	/* call the protocol-specific init routines */
	  InitConnection(conn, protocol, mtu);
	}

	crNetAccept( conn, hostname, port );
	return conn;
}
static void gather_url( RenderSPU *render_spu, const char *response )
{
    char protocol[4096], hostname[4096];
    unsigned short port;
    
    if (!crParseURL(response, protocol, hostname, &port, 0))
    {
        crError( "Malformed URL: \"%s\"", response );
    }

    render_spu->gather_port = port;
}
Esempio n. 5
0
static void injectorspuConnect( void )
{
	char hostname[4096], protocol[4096] ;
	unsigned short port ;

	crNetInit( injectorspuReceiveData, NULL ) ;

	injector_spu.oob_conn = crAlloc( sizeof(CRConnection*) ) ;
	if ( ! crParseURL( injector_spu.oob_url, protocol, hostname, &port, (unsigned short) INJECTORSPU_OOB_PORT ) )
			crError( "Malformed URL: \"%s\"", injector_spu.oob_url ) ;
	injector_spu.oob_conn = crNetAcceptClient( protocol, NULL, (short) port, 32768 /*mtu*/, 0 /*broker*/ ) ;

	/* Initialize the message we send back after every frame */
	injector_spu.info_msg.header.type = CR_MESSAGE_OOB ;
	injector_spu.info_msg.header.conn_id = injector_spu.oob_conn->id ;
	injector_spu.info_msg.frameNum = 0 ;
}
Esempio n. 6
0
void 
CRUT_APIENTRY
crutConnectToClients( CRUTAPI *crut_api )
{   
    int i, ind;     
    char response[8096], hostname[4096], protocol[4096];
    char **newclients;
    char* client;
    unsigned short port;

    crMothershipGetCRUTClients(crut_api->mothershipConn, response);

    newclients = crStrSplit(response, " ");
    crut_api->numclients = crStrToInt(newclients[0]);
    ind = 1;

    crut_api->crutclients = crAlloc(crut_api->numclients*sizeof(CRUTClientPointer));

    for (i=0; i<crut_api->numclients; i++) {
      
        client = newclients[ind++];
	
	if ( !crParseURL( client, protocol, hostname, &port, DEFAULT_CRUT_PORT ) )
	{
	    crError( "Malformed URL: \"%s\"", response );
	}   
	
	crut_api->crutclients[i].mtu = crMothershipGetMTU( crut_api->mothershipConn );
	
	crut_api->crutclients[i].send_conn = crNetAcceptClient( protocol, hostname, port, crut_api->crutclients[i].mtu, 0 );
	
	if (!crut_api->crutclients[i].send_conn)
	{
	    crError("Couldn't connect to the CRUT client");
	}
		    
    }

}
Esempio n. 7
0
/**
 * Establish a connection with a server.
 * \param server  the server to connect to, in the form
 *                "protocol://servername:port" where the port specifier
 *                is optional and if the protocol is missing it is assumed
 *                to be "tcpip".
 * \param default_port  the port to connect to, if port not specified in the
 *                      server URL string.
 * \param mtu  desired maximum transmission unit size (in bytes)
 * \param broker  either 1 or 0 to indicate if connection is brokered through
 *                the mothership
 */
CRConnection * crNetConnectToServer( const char *server, unsigned short default_port, int mtu, int broker
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , struct VBOXUHGSMI *pHgsmi
#endif
)
{
    char hostname[4096], protocol[4096];
    unsigned short port;
    CRConnection *conn;

    crDebug( "In crNetConnectToServer( \"%s\", port=%d, mtu=%d, broker=%d )",
                     server, default_port, mtu, broker );

    CRASSERT( cr_net.initialized );

    if (mtu < CR_MINIMUM_MTU)
    {
        crError( "You tried to connect to server \"%s\" with an mtu of %d, "
                         "but the minimum MTU is %d", server, mtu, CR_MINIMUM_MTU );
    }

    /* Tear the URL apart into relevant portions. */
    if ( !crParseURL( server, protocol, hostname, &port, default_port ) ) {
         crError( "Malformed URL: \"%s\"", server );
    }

    /* If the host name is "localhost" replace it with the _real_ name
     * of the localhost.  If we don't do this, there seems to be
     * confusion in the mothership as to whether or not "localhost" and
     * "foo.bar.com" are the same machine.
     */
    if (crStrcmp(hostname, "localhost") == 0) {
        int rv = crGetHostname(hostname, 4096);
        CRASSERT(rv == 0);
        (void) rv;
    }

    /* XXX why is this here???  I think it could be moved into the
     * crTeacConnection() function with no problem. I.e. change the
     * connection's port, teac_rank and tcscomm_rank there.  (BrianP)
     */
    if ( !crStrcmp( protocol, "quadrics" ) ||
         !crStrcmp( protocol, "quadrics-tcscomm" ) ) {
      /* For Quadrics protocols, treat "port" as "rank" */
      if ( port > CR_QUADRICS_HIGHEST_RANK ) {
        crWarning( "Invalid crserver rank, %d, defaulting to %d\n",
               port, CR_QUADRICS_LOWEST_RANK );
        port = CR_QUADRICS_LOWEST_RANK;
      }
    }
    crDebug( "Connecting to %s on port %d, with protocol %s",
                     hostname, port, protocol );

#ifdef SDP_SUPPORT
    /* This makes me ill, but we need to "fix" the hostname for sdp. MCH */
    if (!crStrcmp(protocol, "sdp")) {
        char* temp;
        temp = strtok(hostname, ".");
        crStrcat(temp, crGetSDPHostnameSuffix());
        crStrcpy(hostname, temp);
        crDebug("SDP rename hostname: %s", hostname);    
    }
#endif

    conn = (CRConnection *) crCalloc( sizeof(*conn) );
    if (!conn)
        return NULL;

    /* init the non-zero fields */
    conn->type               = CR_NO_CONNECTION; /* we don't know yet */
    conn->recv_credits       = CR_INITIAL_RECV_CREDITS;
    conn->hostname           = crStrdup( hostname );
    conn->port               = port;
    conn->mtu                = mtu;
    conn->buffer_size        = mtu;
    conn->broker             = broker;
    conn->endianness         = crDetermineEndianness();
    /* XXX why are these here??? Move them into the crTeacConnection()
     * and crTcscommConnection() functions.
     */
    conn->teac_id            = -1;
    conn->teac_rank          = port;
    conn->tcscomm_id         = -1;
    conn->tcscomm_rank       = port;

    crInitMessageList(&conn->messageList);

    /* now, just dispatch to the appropriate protocol's initialization functions. */
    InitConnection(conn, protocol, mtu
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , pHgsmi
#endif
            );

    if (!crNetConnect( conn ))
    {
        crDebug("crNetConnectToServer() failed, freeing the connection");
        #ifdef CHROMIUM_THREADSAFE
            crFreeMutex( &conn->messageList.lock );
        #endif
        conn->Disconnect(conn);
        crFree( conn );
        return NULL;
    }

    crDebug( "Done connecting to %s (swapping=%d)", server, conn->swap );
    return conn;
}
Esempio n. 8
0
/**
 * This is the main routine responsible for replicating our GL state
 * for a new VNC viewer.  Called when we detect that a new VNC viewer
 * has been started.
 * \param ipaddress  the IP address where the new viewer is running.
 */
void
replicatespuReplicate(int ipaddress) 
{
	GET_THREAD(thread);
	struct in_addr addr;
	char *hosturl;
	char *ipstring;
	int i, r_slot;
	int serverPort;

	crDebug("Replicate SPU: Enter replicatespuReplicate(ipaddress=0x%x)", ipaddress);

	replicatespuFlushAll( (void *)thread );

#ifdef CHROMIUM_THREADSAFE_notyet
	crLockMutex(&_ReplicateMutex);
#endif

	/*
	 * Find empty slot.
	 * Slot 0 is the dummy slot (a non-existant server on devnull connection)
	 */
	for (r_slot = 1; r_slot < CR_MAX_REPLICANTS; r_slot++) {
		if (!IS_CONNECTED(replicate_spu.rserver[r_slot].conn))
			break;
	}
	if (r_slot == CR_MAX_REPLICANTS) {
		crWarning("Replicate SPU: no more replicant slots available");
		return;
	}

	/**
	 ** OK, now rserver[r_slot] is free for use.
	 **/

	/*
	 * At this time, we can only support one VNC viewer per host.
	 * Check for that here.
	 */
	for (i = 1; i < CR_MAX_REPLICANTS; i++) {
		if (replicate_spu.ipnumbers[i] == ipaddress) {
			CRConnection *conn = replicate_spu.rserver[i].conn;
			/* If the connection appears to be active, it may actually be a dangling
			 * connection.  Try flushing it now.  If flushing fails, the connection
			 * type will definitely be CR_NO_CONNECTION (which we test below).
			 */
			if (conn) {
				if (conn->type != CR_NO_CONNECTION) {
					FlushConnection(i);
				}
				if (conn->type != CR_NO_CONNECTION) {
					crWarning("Replicate SPU: Can't connect to multiple VNC viewers on one host.");
#if 0
					/* The above test isn't 100% reliable and can prevent successful
					 * restart of a viewer on a host.  For now, just print warning and
					 * continue.
					 */
					return;
#endif
				}
			}
		}
	}

	replicate_spu.ipnumbers[r_slot] = ipaddress;

	serverPort = replicate_spu.chromium_start_port + r_slot;

	if (replicate_spu.vncAvailable) {
		/* Send a ChromiumStart message to the VNC Server.  The VNC Server will
		 * in turn send a ChromiumStart message to all the attached VNC viewers.
		 * The VNC Viewer/Chromium module will tell its crserver that there's
		 * a new OpenGL client.
		 * We pass the mothership port and crserver port in this message.
		 */
		char protocol[100], hostname[1000];
		const char *mothershipURL;
		unsigned short mothershipPort;
		mothershipURL = crGetenv("CRMOTHERSHIP");
		crDebug("Replicate SPU: CRMOTHERSHIP env var = %s", mothershipURL);
		if (mothershipURL)
			crParseURL(mothershipURL, protocol, hostname, &mothershipPort,
								 DEFAULT_MOTHERSHIP_PORT);
		else
			mothershipPort = DEFAULT_MOTHERSHIP_PORT;
		crDebug("Replicate SPU: Sending ChromiumStart msg to VNC server, port=%d",
						serverPort);

		if (!XVncChromiumStart(replicate_spu.glx_display, ipaddress,
													 serverPort, mothershipPort)) {
			 crWarning("Replicate SPU: XVncChromiumStart() call failed");
		}
	}

	addr.s_addr = ipaddress;
	ipstring = inet_ntoa(addr);
	hosturl = crAlloc(crStrlen(ipstring) + 9);
	sprintf(hosturl, "tcpip://%s", ipstring);

	crDebug("Replicate SPU attaching to %s on port %d", hosturl, serverPort);

	/* connect to the remote VNC server */
	replicate_spu.rserver[r_slot].name = crStrdup( replicate_spu.name );
	replicate_spu.rserver[r_slot].buffer_size = replicate_spu.buffer_size;
	replicate_spu.rserver[r_slot].conn
		= crNetConnectToServer( hosturl, serverPort,
														replicate_spu.rserver[r_slot].buffer_size, 1);

	if (!replicate_spu.rserver[r_slot].conn) {
		crWarning("Replicate SPU: failed to connect to %s", hosturl);
		return;
	}

	CRASSERT(replicate_spu.rserver[r_slot].conn);

	/*
	 * Setup the the packer flush function.  While replicating state to
	 * a particular server we definitely don't want to do any broadcast
	 * flushing!
	 */
	crPackFlushFunc( thread->packer, replicatespuFlushOnePacker );
	crPackSendHugeFunc( thread->packer, replicatespuHugeOnePacker );

	NewServerIndex = r_slot;

	/*
	 * Create server-side windows and contexts by walking tables of app windows
	 * and contexts.  Note that windows can be created in random order,
	 * but contexts must be created in the order they were originally
	 * created, or shared contexts will break.
	 */
	crHashtableWalk(replicate_spu.windowTable, replicatespuReplicateWindow, thread);
	crListApply(replicate_spu.contextList, replicatespuReplicateContext, thread);

	/* MakeCurrent, the current context */
	if (thread->currentContext) {
		int serverWindow = thread->currentContext->currentWindow->id[r_slot];
		int serverContext = thread->currentContext->rserverCtx[r_slot];
		if (replicate_spu.swap)
			crPackMakeCurrentSWAP(serverWindow, 0, serverContext);
	 	else
			crPackMakeCurrent(serverWindow, 0, serverContext);

		crStateMakeCurrent( thread->currentContext->State );
	}

	/*
	 * Set window sizes
	 */
	crHashtableWalk(replicate_spu.windowTable, replicatespuResizeWindows, thread);
	replicatespuFlushOne(thread, NewServerIndex);

	/*
	 * restore normal, broadcasting packer flush function now.
	 */
	crPackFlushFunc( thread->packer, replicatespuFlush );
	crPackSendHugeFunc( thread->packer, replicatespuHuge );

	NewServerIndex = -1;

	crDebug("Replicate SPU: leaving replicatespuReplicate");

#ifdef CHROMIUM_THREADSAFE_notyet
	crUnlockMutex(&_ReplicateMutex);
#endif
}