Annotation of quake2/linux/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 <sys/time.h>
                     27: #include <netinet/in.h>
                     28: #include <netdb.h>
                     29: #include <sys/param.h>
                     30: #include <sys/ioctl.h>
                     31: #include <sys/uio.h>
                     32: #include <errno.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);
1.1.1.2 ! root      302: 
        !           303:                SockadrToNetadr (&from, net_from);
        !           304: 
1.1       root      305:                if (ret == -1)
                    306:                {
                    307:                        err = errno;
                    308: 
                    309:                        if (err == EWOULDBLOCK || err == ECONNREFUSED)
                    310:                                continue;
1.1.1.2 ! root      311:                        Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
        !           312:                                                NET_AdrToString(*net_from));
1.1       root      313:                        continue;
                    314:                }
                    315: 
                    316:                if (ret == net_message->maxsize)
                    317:                {
                    318:                        Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from));
                    319:                        continue;
                    320:                }
                    321: 
                    322:                net_message->cursize = ret;
                    323:                return true;
                    324:        }
                    325: 
                    326:        return false;
                    327: }
                    328: 
                    329: //=============================================================================
                    330: 
                    331: void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to)
                    332: {
                    333:        int             ret;
                    334:        struct sockaddr_in      addr;
                    335:        int             net_socket;
                    336: 
                    337:        if ( to.type == NA_LOOPBACK )
                    338:        {
                    339:                NET_SendLoopPacket (sock, length, data, to);
                    340:                return;
                    341:        }
                    342: 
                    343:        if (to.type == NA_BROADCAST)
                    344:        {
                    345:                net_socket = ip_sockets[sock];
                    346:                if (!net_socket)
                    347:                        return;
                    348:        }
                    349:        else if (to.type == NA_IP)
                    350:        {
                    351:                net_socket = ip_sockets[sock];
                    352:                if (!net_socket)
                    353:                        return;
                    354:        }
                    355:        else if (to.type == NA_IPX)
                    356:        {
                    357:                net_socket = ipx_sockets[sock];
                    358:                if (!net_socket)
                    359:                        return;
                    360:        }
                    361:        else if (to.type == NA_BROADCAST_IPX)
                    362:        {
                    363:                net_socket = ipx_sockets[sock];
                    364:                if (!net_socket)
                    365:                        return;
                    366:        }
                    367:        else
                    368:                Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
                    369: 
                    370:        NetadrToSockadr (&to, &addr);
                    371: 
                    372:        ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
                    373:        if (ret == -1)
                    374:        {
1.1.1.2 ! root      375:                Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
        !           376:                                NET_AdrToString (to));
1.1       root      377:        }
                    378: }
                    379: 
                    380: 
                    381: //=============================================================================
                    382: 
                    383: 
                    384: 
                    385: 
                    386: /*
                    387: ====================
                    388: NET_OpenIP
                    389: ====================
                    390: */
                    391: void NET_OpenIP (void)
                    392: {
                    393:        cvar_t  *port, *ip;
                    394: 
                    395:        port = Cvar_Get ("port", va("%i", PORT_SERVER), CVAR_NOSET);
                    396:        ip = Cvar_Get ("ip", "localhost", CVAR_NOSET);
                    397: 
                    398:        if (!ip_sockets[NS_SERVER])
                    399:                ip_sockets[NS_SERVER] = NET_Socket (ip->string, port->value);
                    400:        if (!ip_sockets[NS_CLIENT])
                    401:                ip_sockets[NS_CLIENT] = NET_Socket (ip->string, PORT_ANY);
                    402: }
                    403: 
                    404: /*
                    405: ====================
                    406: NET_OpenIPX
                    407: ====================
                    408: */
                    409: void NET_OpenIPX (void)
                    410: {
                    411: }
                    412: 
                    413: 
                    414: /*
                    415: ====================
                    416: NET_Config
                    417: 
                    418: A single player game will only use the loopback code
                    419: ====================
                    420: */
                    421: void   NET_Config (qboolean multiplayer)
                    422: {
                    423:        int             i;
                    424: 
                    425:        if (!multiplayer)
                    426:        {       // shut down any existing sockets
                    427:                for (i=0 ; i<2 ; i++)
                    428:                {
                    429:                        if (ip_sockets[i])
                    430:                        {
                    431:                                close (ip_sockets[i]);
                    432:                                ip_sockets[i] = 0;
                    433:                        }
                    434:                        if (ipx_sockets[i])
                    435:                        {
                    436:                                close (ipx_sockets[i]);
                    437:                                ipx_sockets[i] = 0;
                    438:                        }
                    439:                }
                    440:        }
                    441:        else
                    442:        {       // open sockets
                    443:                NET_OpenIP ();
                    444:                NET_OpenIPX ();
                    445:        }
                    446: }
                    447: 
                    448: 
                    449: //===================================================================
                    450: 
                    451: 
                    452: /*
                    453: ====================
                    454: NET_Init
                    455: ====================
                    456: */
                    457: void NET_Init (void)
                    458: {
                    459: }
                    460: 
                    461: 
                    462: /*
                    463: ====================
                    464: NET_Socket
                    465: ====================
                    466: */
                    467: int NET_Socket (char *net_interface, int port)
                    468: {
                    469:        int newsocket;
                    470:        struct sockaddr_in address;
                    471:        qboolean _true = true;
                    472:        int     i = 1;
                    473: 
                    474:        if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
                    475:        {
1.1.1.2 ! root      476:                Com_Printf ("ERROR: UDP_OpenSocket: socket: %s", NET_ErrorString());
1.1       root      477:                return 0;
                    478:        }
                    479: 
                    480:        // make it non-blocking
                    481:        if (ioctl (newsocket, FIONBIO, &_true) == -1)
                    482:        {
                    483:                Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
                    484:                return 0;
                    485:        }
                    486: 
                    487:        // make it broadcast capable
                    488:        if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
                    489:        {
                    490:                Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
                    491:                return 0;
                    492:        }
                    493: 
                    494:        if (!net_interface || !net_interface[0] || !stricmp(net_interface, "localhost"))
                    495:                address.sin_addr.s_addr = INADDR_ANY;
                    496:        else
                    497:                NET_StringToSockaddr (net_interface, (struct sockaddr *)&address);
                    498: 
                    499:        if (port == PORT_ANY)
                    500:                address.sin_port = 0;
                    501:        else
                    502:                address.sin_port = htons((short)port);
                    503: 
                    504:        address.sin_family = AF_INET;
                    505: 
                    506:        if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
                    507:        {
                    508:                Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString());
                    509:                close (newsocket);
                    510:                return 0;
                    511:        }
                    512: 
                    513:        return newsocket;
                    514: }
                    515: 
                    516: 
                    517: /*
                    518: ====================
                    519: NET_Shutdown
                    520: ====================
                    521: */
                    522: void   NET_Shutdown (void)
                    523: {
                    524:        NET_Config (false);     // close sockets
                    525: }
                    526: 
                    527: 
                    528: /*
                    529: ====================
                    530: NET_ErrorString
                    531: ====================
                    532: */
                    533: char *NET_ErrorString (void)
                    534: {
                    535:        int             code;
                    536: 
                    537:        code = errno;
                    538:        return strerror (code);
                    539: }
                    540: 
                    541: // sleeps msec or until net socket is ready
                    542: void NET_Sleep(int msec)
                    543: {
                    544:     struct timeval timeout;
                    545:        fd_set  fdset;
                    546:        extern cvar_t *dedicated;
                    547:        extern qboolean stdin_active;
                    548: 
                    549:        if (!ip_sockets[NS_SERVER] || (dedicated && !dedicated->value))
                    550:                return; // we're not a server, just run full speed
                    551: 
                    552:        FD_ZERO(&fdset);
                    553:        if (stdin_active)
                    554:                FD_SET(0, &fdset); // stdin is processed too
                    555:        FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket
                    556:        timeout.tv_sec = msec/1000;
                    557:        timeout.tv_usec = (msec%1000)*1000;
                    558:        select(ip_sockets[NS_SERVER]+1, &fdset, NULL, NULL, &timeout);
                    559: }
                    560: 

unix.superglobalmegacorp.com

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