Annotation of quake2/solaris/net_udp.c, revision 1.1.1.2

1.1.1.2 ! root        1: /*
        !             2: Copyright (C) 1997-2001 Id Software, Inc.
        !             3: 
        !             4: This program is free software; you can redistribute it and/or
        !             5: modify it under the terms of the GNU General Public License
        !             6: as published by the Free Software Foundation; either version 2
        !             7: of the License, or (at your option) any later version.
        !             8: 
        !             9: This program is distributed in the hope that it will be useful,
        !            10: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
        !            12: 
        !            13: See the GNU General Public License for more details.
        !            14: 
        !            15: You should have received a copy of the GNU General Public License
        !            16: along with this program; if not, write to the Free Software
        !            17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
        !            18: 
        !            19: */
1.1       root       20: // net_wins.c
                     21: 
                     22: #include "../qcommon/qcommon.h"
                     23: 
                     24: #include <unistd.h>
                     25: #include <sys/socket.h>
                     26: #include <netinet/in.h>
                     27: #include <netdb.h>
                     28: #include <sys/param.h>
                     29: #include <sys/ioctl.h>
                     30: #include <sys/uio.h>
                     31: #include <errno.h>
                     32: #include <sys/filio.h>
                     33: 
                     34: #ifdef NeXT
                     35: #include <libc.h>
                     36: #endif
                     37: 
                     38: netadr_t       net_local_adr;
                     39: 
                     40: #define        LOOPBACK        0x7f000001
                     41: 
                     42: #define        MAX_LOOPBACK    4
                     43: 
                     44: typedef struct
                     45: {
                     46:        byte    data[MAX_MSGLEN];
                     47:        int             datalen;
                     48: } loopmsg_t;
                     49: 
                     50: typedef struct
                     51: {
                     52:        loopmsg_t       msgs[MAX_LOOPBACK];
                     53:        int                     get, send;
                     54: } loopback_t;
                     55: 
                     56: loopback_t     loopbacks[2];
                     57: int                    ip_sockets[2];
                     58: int                    ipx_sockets[2];
                     59: 
                     60: int NET_Socket (char *net_interface, int port);
                     61: char *NET_ErrorString (void);
                     62: 
                     63: //=============================================================================
                     64: 
                     65: void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s)
                     66: {
                     67:        memset (s, 0, sizeof(*s));
                     68: 
                     69:        if (a->type == NA_BROADCAST)
                     70:        {
                     71:                s->sin_family = AF_INET;
                     72: 
                     73:                s->sin_port = a->port;
                     74:                *(int *)&s->sin_addr = -1;
                     75:        }
                     76:        else if (a->type == NA_IP)
                     77:        {
                     78:                s->sin_family = AF_INET;
                     79: 
                     80:                *(int *)&s->sin_addr = *(int *)&a->ip;
                     81:                s->sin_port = a->port;
                     82:        }
                     83: }
                     84: 
                     85: void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a)
                     86: {
                     87:        *(int *)&a->ip = *(int *)&s->sin_addr;
                     88:        a->port = s->sin_port;
                     89:        a->type = NA_IP;
                     90: }
                     91: 
                     92: 
                     93: qboolean       NET_CompareAdr (netadr_t a, netadr_t b)
                     94: {
                     95:        if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port)
                     96:                return true;
                     97:        return false;
                     98: }
                     99: 
                    100: /*
                    101: ===================
                    102: NET_CompareBaseAdr
                    103: 
                    104: Compares without the port
                    105: ===================
                    106: */
                    107: qboolean       NET_CompareBaseAdr (netadr_t a, netadr_t b)
                    108: {
                    109:        if (a.type != b.type)
                    110:                return false;
                    111: 
                    112:        if (a.type == NA_LOOPBACK)
                    113:                return true;
                    114: 
                    115:        if (a.type == NA_IP)
                    116:        {
                    117:                if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3])
                    118:                        return true;
                    119:                return false;
                    120:        }
                    121: 
                    122:        if (a.type == NA_IPX)
                    123:        {
                    124:                if ((memcmp(a.ipx, b.ipx, 10) == 0))
                    125:                        return true;
                    126:                return false;
                    127:        }
                    128: }
                    129: 
                    130: char   *NET_AdrToString (netadr_t a)
                    131: {
                    132:        static  char    s[64];
                    133:        
                    134:        Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port));
                    135: 
                    136:        return s;
                    137: }
                    138: 
                    139: char   *NET_BaseAdrToString (netadr_t a)
                    140: {
                    141:        static  char    s[64];
                    142:        
                    143:        Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
                    144: 
                    145:        return s;
                    146: }
                    147: 
                    148: /*
                    149: =============
                    150: NET_StringToAdr
                    151: 
                    152: localhost
                    153: idnewt
                    154: idnewt:28000
                    155: 192.246.40.70
                    156: 192.246.40.70:28000
                    157: =============
                    158: */
                    159: qboolean       NET_StringToSockaddr (char *s, struct sockaddr *sadr)
                    160: {
                    161:        struct hostent  *h;
                    162:        char    *colon;
                    163:        char    copy[128];
                    164:        
                    165:        memset (sadr, 0, sizeof(*sadr));
                    166:        ((struct sockaddr_in *)sadr)->sin_family = AF_INET;
                    167:        
                    168:        ((struct sockaddr_in *)sadr)->sin_port = 0;
                    169: 
                    170:        strcpy (copy, s);
                    171:        // strip off a trailing :port if present
                    172:        for (colon = copy ; *colon ; colon++)
                    173:                if (*colon == ':')
                    174:                {
                    175:                        *colon = 0;
                    176:                        ((struct sockaddr_in *)sadr)->sin_port = htons((short)atoi(colon+1));   
                    177:                }
                    178:        
                    179:        if (copy[0] >= '0' && copy[0] <= '9')
                    180:        {
                    181:                *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(copy);
                    182:        }
                    183:        else
                    184:        {
                    185:                if (! (h = gethostbyname(copy)) )
                    186:                        return 0;
                    187:                *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
                    188:        }
                    189:        
                    190:        return true;
                    191: }
                    192: 
                    193: /*
                    194: =============
                    195: NET_StringToAdr
                    196: 
                    197: localhost
                    198: idnewt
                    199: idnewt:28000
                    200: 192.246.40.70
                    201: 192.246.40.70:28000
                    202: =============
                    203: */
                    204: qboolean       NET_StringToAdr (char *s, netadr_t *a)
                    205: {
                    206:        struct sockaddr_in sadr;
                    207:        
                    208:        if (!strcmp (s, "localhost"))
                    209:        {
                    210:                memset (a, 0, sizeof(*a));
                    211:                a->type = NA_LOOPBACK;
                    212:                return true;
                    213:        }
                    214: 
                    215:        if (!NET_StringToSockaddr (s, (struct sockaddr *)&sadr))
                    216:                return false;
                    217:        
                    218:        SockadrToNetadr (&sadr, a);
                    219: 
                    220:        return true;
                    221: }
                    222: 
                    223: 
                    224: qboolean       NET_IsLocalAddress (netadr_t adr)
                    225: {
                    226:        return NET_CompareAdr (adr, net_local_adr);
                    227: }
                    228: 
                    229: /*
                    230: =============================================================================
                    231: 
                    232: LOOPBACK BUFFERS FOR LOCAL PLAYER
                    233: 
                    234: =============================================================================
                    235: */
                    236: 
                    237: qboolean       NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
                    238: {
                    239:        int             i;
                    240:        loopback_t      *loop;
                    241: 
                    242:        loop = &loopbacks[sock];
                    243: 
                    244:        if (loop->send - loop->get > MAX_LOOPBACK)
                    245:                loop->get = loop->send - MAX_LOOPBACK;
                    246: 
                    247:        if (loop->get >= loop->send)
                    248:                return false;
                    249: 
                    250:        i = loop->get & (MAX_LOOPBACK-1);
                    251:        loop->get++;
                    252: 
                    253:        memcpy (net_message->data, loop->msgs[i].data, loop->msgs[i].datalen);
                    254:        net_message->cursize = loop->msgs[i].datalen;
                    255:        *net_from = net_local_adr;
                    256:        return true;
                    257: 
                    258: }
                    259: 
                    260: 
                    261: void NET_SendLoopPacket (netsrc_t sock, int length, void *data, netadr_t to)
                    262: {
                    263:        int             i;
                    264:        loopback_t      *loop;
                    265: 
                    266:        loop = &loopbacks[sock^1];
                    267: 
                    268:        i = loop->send & (MAX_LOOPBACK-1);
                    269:        loop->send++;
                    270: 
                    271:        memcpy (loop->msgs[i].data, data, length);
                    272:        loop->msgs[i].datalen = length;
                    273: }
                    274: 
                    275: //=============================================================================
                    276: 
                    277: qboolean       NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
                    278: {
                    279:        int     ret;
                    280:        struct sockaddr_in      from;
                    281:        int             fromlen;
                    282:        int             net_socket;
                    283:        int             protocol;
                    284:        int             err;
                    285: 
                    286:        if (NET_GetLoopPacket (sock, net_from, net_message))
                    287:                return true;
                    288: 
                    289:        for (protocol = 0 ; protocol < 2 ; protocol++)
                    290:        {
                    291:                if (protocol == 0)
                    292:                        net_socket = ip_sockets[sock];
                    293:                else
                    294:                        net_socket = ipx_sockets[sock];
                    295: 
                    296:                if (!net_socket)
                    297:                        continue;
                    298: 
                    299:                fromlen = sizeof(from);
                    300:                ret = recvfrom (net_socket, net_message->data, net_message->maxsize
                    301:                        , 0, (struct sockaddr *)&from, &fromlen);
                    302:                if (ret == -1)
                    303:                {
                    304:                        err = errno;
                    305: 
                    306:                        if (err == EWOULDBLOCK || err == ECONNREFUSED)
                    307:                                continue;
                    308:                        Com_Printf ("NET_GetPacket: %s", NET_ErrorString());
                    309:                        continue;
                    310:                }
                    311: 
                    312:                if (ret == net_message->maxsize)
                    313:                {
                    314:                        Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from));
                    315:                        continue;
                    316:                }
                    317: 
                    318:                net_message->cursize = ret;
                    319:                SockadrToNetadr (&from, net_from);
                    320:                return true;
                    321:        }
                    322: 
                    323:        return false;
                    324: }
                    325: 
                    326: //=============================================================================
                    327: 
                    328: void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to)
                    329: {
                    330:        int             ret;
                    331:        struct sockaddr_in      addr;
                    332:        int             net_socket;
                    333: 
                    334:        if ( to.type == NA_LOOPBACK )
                    335:        {
                    336:                NET_SendLoopPacket (sock, length, data, to);
                    337:                return;
                    338:        }
                    339: 
                    340:        if (to.type == NA_BROADCAST)
                    341:        {
                    342:                net_socket = ip_sockets[sock];
                    343:                if (!net_socket)
                    344:                        return;
                    345:        }
                    346:        else if (to.type == NA_IP)
                    347:        {
                    348:                net_socket = ip_sockets[sock];
                    349:                if (!net_socket)
                    350:                        return;
                    351:        }
                    352:        else if (to.type == NA_IPX)
                    353:        {
                    354:                net_socket = ipx_sockets[sock];
                    355:                if (!net_socket)
                    356:                        return;
                    357:        }
                    358:        else if (to.type == NA_BROADCAST_IPX)
                    359:        {
                    360:                net_socket = ipx_sockets[sock];
                    361:                if (!net_socket)
                    362:                        return;
                    363:        }
                    364:        else
                    365:                Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
                    366: 
                    367:        NetadrToSockadr (&to, &addr);
                    368: 
                    369:        ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
                    370:        if (ret == -1)
                    371:        {
                    372:                Com_Printf ("NET_SendPacket ERROR: %i\n", NET_ErrorString());
                    373:        }
                    374: }
                    375: 
                    376: 
                    377: //=============================================================================
                    378: 
                    379: 
                    380: 
                    381: 
                    382: /*
                    383: ====================
                    384: NET_OpenIP
                    385: ====================
                    386: */
                    387: void NET_OpenIP (void)
                    388: {
                    389:        cvar_t  *port, *ip;
                    390: 
                    391:        port = Cvar_Get ("port", va("%i", PORT_SERVER), CVAR_NOSET);
                    392:        ip = Cvar_Get ("ip", "localhost", CVAR_NOSET);
                    393: 
                    394:        if (!ip_sockets[NS_SERVER])
                    395:                ip_sockets[NS_SERVER] = NET_Socket (ip->string, port->value);
                    396:        if (!ip_sockets[NS_CLIENT])
                    397:                ip_sockets[NS_CLIENT] = NET_Socket (ip->string, PORT_ANY);
                    398: }
                    399: 
                    400: /*
                    401: ====================
                    402: NET_OpenIPX
                    403: ====================
                    404: */
                    405: void NET_OpenIPX (void)
                    406: {
                    407: }
                    408: 
                    409: 
                    410: /*
                    411: ====================
                    412: NET_Config
                    413: 
                    414: A single player game will only use the loopback code
                    415: ====================
                    416: */
                    417: void   NET_Config (qboolean multiplayer)
                    418: {
                    419:        int             i;
                    420: 
                    421:        if (!multiplayer)
                    422:        {       // shut down any existing sockets
                    423:                for (i=0 ; i<2 ; i++)
                    424:                {
                    425:                        if (ip_sockets[i])
                    426:                        {
                    427:                                close (ip_sockets[i]);
                    428:                                ip_sockets[i] = 0;
                    429:                        }
                    430:                        if (ipx_sockets[i])
                    431:                        {
                    432:                                close (ipx_sockets[i]);
                    433:                                ipx_sockets[i] = 0;
                    434:                        }
                    435:                }
                    436:        }
                    437:        else
                    438:        {       // open sockets
                    439:                NET_OpenIP ();
                    440:                NET_OpenIPX ();
                    441:        }
                    442: }
                    443: 
                    444: 
                    445: //===================================================================
                    446: 
                    447: 
                    448: /*
                    449: ====================
                    450: NET_Init
                    451: ====================
                    452: */
                    453: void NET_Init (void)
                    454: {
                    455: }
                    456: 
                    457: 
                    458: /*
                    459: ====================
                    460: NET_Socket
                    461: ====================
                    462: */
                    463: int NET_Socket (char *net_interface, int port)
                    464: {
                    465:        int newsocket;
                    466:        struct sockaddr_in address;
                    467:        qboolean _true = true;
                    468:        int     i = 1;
                    469: 
                    470:        if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
                    471:        {
                    472:                Com_Printf ("ERROR: UDP_OpenSocket: socket:", NET_ErrorString());
                    473:                return 0;
                    474:        }
                    475: 
                    476:        // make it non-blocking
                    477:        if (ioctl (newsocket, FIONBIO, &_true) == -1)
                    478:        {
                    479:                Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
                    480:                return 0;
                    481:        }
                    482: 
                    483:        // make it broadcast capable
                    484:        if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
                    485:        {
                    486:                Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
                    487:                return 0;
                    488:        }
                    489: 
                    490:        if (!net_interface || !net_interface[0] || !stricmp(net_interface, "localhost"))
                    491:                address.sin_addr.s_addr = INADDR_ANY;
                    492:        else
                    493:                NET_StringToSockaddr (net_interface, (struct sockaddr *)&address);
                    494: 
                    495:        if (port == PORT_ANY)
                    496:                address.sin_port = 0;
                    497:        else
                    498:                address.sin_port = htons((short)port);
                    499: 
                    500:        address.sin_family = AF_INET;
                    501: 
                    502:        if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
                    503:        {
                    504:                Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString());
                    505:                close (newsocket);
                    506:                return 0;
                    507:        }
                    508: 
                    509:        return newsocket;
                    510: }
                    511: 
                    512: 
                    513: /*
                    514: ====================
                    515: NET_Shutdown
                    516: ====================
                    517: */
                    518: void   NET_Shutdown (void)
                    519: {
                    520:        NET_Config (false);     // close sockets
                    521: }
                    522: 
                    523: 
                    524: /*
                    525: ====================
                    526: NET_ErrorString
                    527: ====================
                    528: */
                    529: char *NET_ErrorString (void)
                    530: {
                    531:        int             code;
                    532: 
                    533:        code = errno;
                    534:        return strerror (code);
                    535: }
                    536: 
                    537: // sleeps msec or until net socket is ready
                    538: void NET_Sleep(int msec)
                    539: {
                    540:     struct timeval timeout;
                    541:        fd_set  fdset;
                    542:        extern cvar_t *dedicated;
                    543:        extern qboolean stdin_active;
                    544: 
                    545:        if (!ip_sockets[NS_SERVER] || (dedicated && !dedicated->value))
                    546:                return; // we're not a server, just run full speed
                    547: 
                    548:        FD_ZERO(&fdset);
                    549:        if (stdin_active)
                    550:                FD_SET(0, &fdset); // stdin is processed too
                    551:        FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket
                    552:        timeout.tv_sec = msec/1000;
                    553:        timeout.tv_usec = (msec%1000)*1000;
                    554:        select(ip_sockets[NS_SERVER]+1, &fdset, NULL, NULL, &timeout);
                    555: }
                    556: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.