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

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

unix.superglobalmegacorp.com

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