Ejemplo n.º 1
0
Archivo: net.c Proyecto: ewirch/qfusion
/*
* NET_TCP_Send
*/
static int NET_TCP_Send( const socket_t *socket, const void *data, size_t length )
{
#ifdef USE_TCP_NOSIGPIPE
    int opt_val = 1;
#endif
    int ret;

    assert( socket && socket->open && socket->type == SOCKET_TCP );
    assert( data );
    assert( length > 0 );

#ifdef USE_TCP_NOSIGPIPE
    // Disable SIGPIPE
    // Currently ignore the return code from setsockopt
    setsockopt( socket->handle, SOL_SOCKET, SO_NOSIGPIPE, &opt_val, sizeof( opt_val ) );
#endif

    ret = send( socket->handle, data, length, MSG_NOSIGNAL );

#ifdef USE_TCP_NOSIGPIPE
    // Enable SIGPIPE
    opt_val = 0;
    setsockopt( socket->handle, SOL_SOCKET, SO_NOSIGPIPE, &opt_val, sizeof( opt_val ) );
#endif

    if( ret == SOCKET_ERROR )
    {
        NET_SetErrorStringFromLastError( "send" );
        if( Sys_NET_GetLastError() == NET_ERR_WOULDBLOCK )  // would block
            return 0;
        return -1;
    }

    return ret;
}
Ejemplo n.º 2
0
Archivo: net.c Proyecto: ewirch/qfusion
/*
* NET_TCP_Connect
*/
static connection_status_t NET_TCP_Connect( socket_t *socket, const netadr_t *address )
{
    struct sockaddr_storage sockaddress;
    socklen_t addrlen;

    assert( socket && socket->open && socket->type == SOCKET_TCP && socket->handle && !socket->connected );
    assert( address );

    if( !AddressToSockaddress( address, &sockaddress ) )
        return CONNECTION_FAILED;

    addrlen = ( sockaddress.ss_family == AF_INET6 ? sizeof( struct sockaddr_in6 ) : sizeof( struct sockaddr_in ) );
    if( connect( socket->handle, (struct sockaddr*)&sockaddress, addrlen ) == SOCKET_ERROR )
    {
        net_error_t err;

        err = Sys_NET_GetLastError();
        if( err == NET_ERR_INPROGRESS || err == NET_ERR_WOULDBLOCK )
        {
            socket->remoteAddress = *address;
            return CONNECTION_INPROGRESS;
        }
        else
        {
            NET_SetErrorStringFromLastError( "connect" );
            return CONNECTION_FAILED;
        }
    }

    socket->connected = qtrue;
    socket->remoteAddress = *address;

    return CONNECTION_SUCCEEDED;
}
Ejemplo n.º 3
0
Archivo: net.c Proyecto: cfr/qfusion
/*
* NET_SendFile
*/
int64_t NET_SendFile( const socket_t *socket, int file, size_t offset, size_t count, const netadr_t *address )
{
	int ret, err;

	assert( socket->open );

	if( !socket->open )
		return -1;

	if( address->type == NA_NOTRANSMIT )
		return -1;

#ifndef TCP_SUPPORT
	return -1;
#else
	if( socket->type != SOCKET_TCP )
		return -1;

	ret = Sys_NET_SendFile( socket->handle, file, offset, count );
	if( ret == SOCKET_ERROR )
	{
		NET_SetErrorStringFromLastError( "sendfile" );

		err = Sys_NET_GetLastError();
		if( err == NET_ERR_WOULDBLOCK || err == NET_ERR_CONNRESET )  // would block
			return 0;

		return -1;
	}

	return ret;
#endif
}
Ejemplo n.º 4
0
Archivo: net.c Proyecto: j0ki/racesow
/*
* GetLastErrorString
*/
static const char *GetLastErrorString( void )
{
	switch( Sys_NET_GetLastError() )
	{
	case NET_ERR_UNKNOWN:		return "Unknown error";
	case NET_ERR_NONE:			return "No error";

	case NET_ERR_CONNRESET:		return "Connection reset or refused";
	case NET_ERR_INPROGRESS:	return "Operation in progress";
	case NET_ERR_MSGSIZE:		return "Oversized packet";
	case NET_ERR_WOULDBLOCK:	return "Operation should have blocked";
	case NET_ERR_UNSUPPORTED:	return "Unsupported address or protocol";
	default:					return "Unsupported error code";
	}
}
Ejemplo n.º 5
0
Archivo: net.c Proyecto: ewirch/qfusion
/*
* NET_UDP_GetPacket
*/
static int NET_UDP_GetPacket( const socket_t *socket, netadr_t *address, msg_t *message )
{
    struct sockaddr_storage from;
    socklen_t fromlen;
    int ret;

    assert( socket && socket->open && socket->type == SOCKET_UDP );
    assert( address );
    assert( message );
    assert( message->data );
    assert( message->maxsize > 0 );

    fromlen = sizeof( from );
    ret = recvfrom( socket->handle, (char*)message->data, message->maxsize, 0, (struct sockaddr *)&from, &fromlen );
    if( ret == SOCKET_ERROR )
    {
        net_error_t err;

        NET_SetErrorStringFromLastError( "recvfrom" );

        err = Sys_NET_GetLastError();
        if( err == NET_ERR_WOULDBLOCK || err == NET_ERR_CONNRESET )  // would block
            return 0;

        return -1;
    }

    if( !SockaddressToAddress( (struct sockaddr*)&from, address ) )
        return -1;

    if( ret == (int)message->maxsize )
    {
        NET_SetErrorString( "Oversized packet" );
        return -1;
    }

    message->readcount = 0;
    message->cursize = ret;

    return 1;
}
Ejemplo n.º 6
0
Archivo: net.c Proyecto: ewirch/qfusion
/*
* NET_TCP_Accept
*/
static int NET_TCP_Accept( const socket_t *socket, socket_t *newsocket, netadr_t *address )
{
    struct sockaddr_storage sockaddress;
    socklen_t sockaddress_size;
    int handle;

    assert( socket && socket->open && socket->type == SOCKET_TCP && socket->handle );
    assert( newsocket );
    assert( address );

    sockaddress_size = sizeof( sockaddress );
    handle = accept( socket->handle, (struct sockaddr *)&sockaddress, &sockaddress_size );
    if( handle == SOCKET_ERROR )
    {
        NET_SetErrorStringFromLastError( "accept" );
        if( Sys_NET_GetLastError() == NET_ERR_WOULDBLOCK )  // would block
            return 0;
        return -1;
    }

    if( !SockaddressToAddress( (struct sockaddr *)&sockaddress, address ) )
        return -1;

    // make the new socket non-blocking
    if( !NET_SocketMakeNonBlocking( handle ) )
    {
        Sys_NET_SocketClose( handle );
        return -1;
    }

    newsocket->open = qtrue;
    newsocket->type = SOCKET_TCP;
    newsocket->server = socket->server;
    newsocket->address = socket->address;
    newsocket->remoteAddress = *address;
    newsocket->handle = handle;

    return 1;
}
Ejemplo n.º 7
0
Archivo: net.c Proyecto: ewirch/qfusion
/*
* NET_TCP_Get
*/
static int NET_TCP_Get( const socket_t *socket, netadr_t *address, void *data, size_t length )
{
    int ret;

    assert( socket && socket->open && socket->type == SOCKET_TCP );
    assert( data );
    assert( length > 0 );

    ret = recv( socket->handle, data, length, 0 );
    if( ret == SOCKET_ERROR )
    {
        NET_SetErrorStringFromLastError( "recv" );
        if( Sys_NET_GetLastError() == NET_ERR_WOULDBLOCK )  // would block
            return 0;
        return -1;
    }

    if( address )
        *address = socket->remoteAddress;

    return ret;
}
Ejemplo n.º 8
0
Archivo: net.c Proyecto: ewirch/qfusion
/*
* NET_TCP_GetPacket
*/
static int NET_TCP_GetPacket( const socket_t *socket, netadr_t *address, msg_t *message )
{
    int ret;
    qbyte buffer[MAX_PACKETLEN + 4];
    int len;

    assert( socket && socket->open && socket->connected && socket->type == SOCKET_TCP );
    assert( address );
    assert( message );

    // peek the message to see if the whole packet is ready
    ret = recv( socket->handle, (char*)buffer, sizeof( buffer ), MSG_PEEK );
    if( ret == SOCKET_ERROR )
    {
        NET_SetErrorStringFromLastError( "recv" );
        if( Sys_NET_GetLastError() == NET_ERR_WOULDBLOCK )  // would block
            return 0;
        return -1;
    }

    if( ret < 4 )  // the length information is not yet received
        return 0;

    memcpy( &len, buffer, 4 );
    len = LittleLong( len );

    if( len > MAX_PACKETLEN || len > (int)message->maxsize )
    {
        NET_SetErrorString( "Oversized packet" );
        return -1;
    }

    if( ret < len + 4 )  // the whole packet is not yet ready
        return 0;

    // ok we have the whole packet ready, get it

    // read the 4 byte header
    ret = NET_TCP_Get( socket, NULL, buffer, 4 );
    if( ret == -1 )
        return -1;
    if( ret != 4 )
    {
        NET_SetErrorString( "Couldn't read the whole packet" );
        return -1;
    }

    ret = NET_TCP_Get( socket, NULL, message->data, len );
    if( ret == SOCKET_ERROR )
        return -1;
    if( ret != (int)len )
    {
        NET_SetErrorString( "Couldn't read the whole packet" );
        return -1;
    }

    *address = socket->remoteAddress;

    message->readcount = 0;
    message->cursize = ret;

    return qtrue;
}