1 /*
2   HawkNL cross platform network library
3   Copyright (C) 2000-2002 Phil Frisbie, Jr. (phil@hawksoft.com)
4 
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Library General Public
7   License as published by the Free Software Foundation; either
8   version 2 of the License, or (at your option) any later version.
9 
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Library General Public License for more details.
14 
15   You should have received a copy of the GNU Library General Public
16   License along with this library; if not, write to the
17   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18   Boston, MA  02111-1307, USA.
19 
20   Or go to http://www.gnu.org/copyleft/lgpl.html
21 */
22 
23 #ifndef INTERNAL_H
24 #define INTERNAL_H
25 
26 #include "../include/nl.h"
27 
28 /* for malloc and free */
29 #include <stdlib.h>
30 
31 /* Windows CE does not have time.h functions */
32 #if defined (_WIN32_WCE)
33 extern time_t time(time_t *timer);
34 #else
35 #include <time.h>
36 #endif
37 
38 
39 #ifdef NL_LITTLE_ENDIAN
40 #define NL_SWAP_TRUE (nlState.nl_big_endian_data == NL_TRUE)
41 #else
42 #define NL_SWAP_TRUE (nlState.nl_big_endian_data != NL_TRUE)
43 #endif /* NL_LITTLE_ENDIAN */
44 
45 #ifdef WINDOWS_APP
46 /* Windows systems */
47 #ifdef _MSC_VER
48 #pragma warning (disable:4201)
49 #pragma warning (disable:4214)
50 #endif /* _MSC_VER */
51 
52 #define WIN32_LEAN_AND_MEAN
53 #include <windows.h>
54 #include <tchar.h>
55 
56 #ifdef _MSC_VER
57 #pragma warning (default:4201)
58 #pragma warning (default:4214)
59 #endif /* _MSC_VER */
60 
61 #endif
62 
63 /* part of portable unicode support */
64 #if !defined _TCHAR_DEFINED && !(defined _WCHAR_T_DEFINED && defined (__LCC__))
65 #ifdef _UNICODE
66 #define TEXT(x)    L##x
67 #define _tcsncat    wcsncat
68 #define _stprintf   swprintf
69 #define _sntprintf  snwprintf
70 #define _stscanf    swscanf
71 #define _tcsncpy    wcsncpy
72 #define _tcscspn    wcscspn
73 #define _tcschr     wcschr
74 #define _tcslen     wcslen
75 #define _tcsrchr    wcsrchr
76 #ifdef WINDOWS_APP
77 #define _ttoi       _wtoi
78 #else /* !WINDOWS_APP*/
79 #define _ttoi       wtoi
80 #endif /* !WINDOWS_APP*/
81 #else /* !UNICODE */
82 #define TEXT(x)    x
83 #define _tcsncat    strncat
84 #define _stprintf   sprintf
85 #define _sntprintf  snprintf
86 #define _stscanf    sscanf
87 #define _tcsncpy    strncpy
88 #define _tcscspn    strcspn
89 #define _tcschr     strchr
90 #define _tcslen     strlen
91 #define _ttoi       atoi
92 #define _tcsrchr    strrchr
93 #endif /* !UNICODE */
94 #endif /* _INC_TCHAR */
95 
96 
97 #define NL_FIRST_GROUP          (200000 + 1)
98 
99 /* the minumum number of sockets that will be allocated */
100 #define NL_MIN_SOCKETS          16
101 
102 /* number of buckets for average bytes/second */
103 #define NL_NUM_BUCKETS          8
104 
105 /* number of packets stored for NL_LOOP_BACK */
106 #define NL_NUM_PACKETS          8
107 #define NL_MAX_ACCEPT           10
108 
109 /* for nlLockSocket and nlUnlockSocket */
110 #define NL_READ                 0x0001
111 #define NL_WRITE                0x0002
112 #define NL_BOTH                 (NL_READ|NL_WRITE)
113 
114 /* time in milliseconds that unreliable connect/accepts sleep while waiting */
115 #define NL_CONNECT_SLEEP    50
116 
117 #ifdef __cplusplus
118 extern "C" {
119 #endif
120 
121 /* the driver object */
122 typedef struct
123 {
124     const NLchar /*@observer@*/*name;
125     const NLchar /*@observer@*/*connections;
126     NLenum      type;
127     NLboolean   initialized;
128     NLboolean   (*Init)(void);
129     void        (*Shutdown)(void);
130     NLboolean   (*Listen)(NLsocket socket);
131     NLsocket    (*AcceptConnection)(NLsocket socket);
132     NLsocket    (*Open)(NLushort port, NLenum type);
133     NLboolean   (*Connect)(NLsocket socket, const NLaddress *address);
134     void        (*Close)(NLsocket socket);
135     NLint       (*Read)(NLsocket socket, /*@out@*/ NLvoid *buffer, NLint nbytes);
136     NLint       (*Write)(NLsocket socket, const NLvoid *buffer, NLint nbytes);
137     NLchar      *(*AddrToString)(const NLaddress *address, /*@returned@*/ /*@out@*/ NLchar *string);
138     NLboolean   (*StringToAddr)(const NLchar *string, /*@out@*/ NLaddress *address);
139     NLboolean   (*GetLocalAddr)(NLsocket socket, /*@out@*/ NLaddress *address);
140     NLaddress   *(*GetAllLocalAddr)(/*@out@*/ NLint *count);
141     NLboolean   (*SetLocalAddr)(const NLaddress *address);
142     NLchar      *(*GetNameFromAddr)(const NLaddress *address, /*@returned@*/ /*@out@*/ NLchar *name);
143     NLboolean   (*GetNameFromAddrAsync)(const NLaddress *address, /*@out@*/ NLchar *name);
144     NLboolean   (*GetAddrFromName)(const NLchar *name, /*@out@*/ NLaddress *address);
145     NLboolean   (*GetAddrFromNameAsync)(const NLchar *name, /*@out@*/ NLaddress *address);
146     NLboolean   (*AddrCompare)(const NLaddress *address1, const NLaddress *address2);
147     NLushort    (*GetPortFromAddr)(const NLaddress *address);
148     void        (*SetAddrPort)(NLaddress *address, NLushort port);
149     NLint       (*GetSystemError)(void);
150     NLint       (*PollGroup)(NLint group, NLenum name, /*@out@*/ NLsocket *sockets,
151                                 NLint number, NLint timeout);
152     NLboolean   (*Hint)(NLenum name, NLint arg);
153 } nl_netdriver_t;
154 
155 typedef struct
156 {
157     NLlong      bytes;          /* bytes sent/received */
158     NLlong      packets;        /* packets sent/received */
159     NLlong      highest;        /* highest bytes/sec sent/received */
160     NLlong      average;        /* average bytes/sec sent/received */
161     time_t      stime;          /* the last time stats were updated */
162     NLint       lastbucket;     /* the last bucket that was used */
163     NLlong      curbytes;       /* current bytes sent/received */
164     NLlong      bucket[NL_NUM_BUCKETS];/* buckets for sent/received counts */
165     NLboolean   firstround;     /* is this the first round through the buckets? */
166 } nl_stats_t;
167 
168 typedef struct
169 {
170     /* info for NL_LOOP_BACK, NL_SERIAL, and NL_PARALLEL */
171     NLbyte      *outpacket[NL_NUM_PACKETS];/* temp storage for packet data */
172     NLbyte      *inpacket[NL_NUM_PACKETS];/* temp storage for packet data */
173     NLint       outlen[NL_NUM_PACKETS];/* the length of each packet */
174     NLint       inlen[NL_NUM_PACKETS];/* the length of each packet */
175     NLint       nextoutused;    /* the next used packet */
176     NLint       nextinused;     /* the next used packet */
177     NLint       nextoutfree;    /* the next free packet */
178     NLint       nextinfree;     /* the next free packet */
179     NLsocket    accept[NL_MAX_ACCEPT];/* pending connects */
180     NLsocket    consock;        /* the socket this socket is connected to */
181 } nl_extra_t;
182 
183 /* the internal socket object */
184 typedef struct
185 {
186     /* the current status of the socket */
187     NLenum      driver;         /* the driver used with this socket */
188     NLenum      type;           /* type of socket */
189     NLboolean   inuse;          /* is in use */
190     NLboolean   connecting;     /* a non-blocking TCP or UDP connection is in process */
191     NLboolean   conerror;       /* an error occured on a UDP connect */
192     NLboolean   connected;      /* is connected */
193     NLboolean   reliable;       /* do we use reliable */
194     NLboolean   blocking;       /* is set to blocking */
195     NLboolean   listen;         /* can receive an incoming connection */
196     NLint       realsocket;     /* the real socket number */
197     NLushort    localport;      /* local port number */
198     NLushort    remoteport;     /* remote port number */
199     NLaddress   addressin;      /* address of remote system, same as the socket sockaddr_in structure */
200     NLaddress   addressout;     /* the multicast address set by nlConnect or the remote address for unconnected UDP */
201     NLmutex     readlock;       /* socket is locked to update data */
202     NLmutex     writelock;      /* socket is locked to update data */
203 
204     /* the current read/write statistics for the socket */
205     nl_stats_t  instats;        /* stats for received */
206     nl_stats_t  outstats;       /* stats for sent */
207 
208     /* NL_RELIABLE_PACKETS info and storage */
209     NLbyte      *outbuf;        /* temp storage for partially sent reliable packet data */
210     NLint       outbuflen;      /* the length of outbuf */
211     NLint       sendlen;        /* how much still needs to be sent */
212     NLbyte      *inbuf;         /* temp storage for partially received reliable packet data */
213     NLint       inbuflen;       /* the length of inbuf */
214     NLint       reclen;         /* how much of the reliable packet we have received */
215     NLboolean   readable;       /* a complete packet is in inbuf */
216     NLboolean   message_end;    /* a message end error ocured but was not yet reported */
217     NLboolean   packetsync;     /* is the reliable packet stream in sync */
218     /* pointer to extra info needed for NL_LOOP_BACK, NL_SERIAL, and NL_PARALLEL */
219     nl_extra_t   *ext;
220 } nl_socket_t;
221 
222 typedef struct
223 {
224     NLboolean   socketStats;    /* enable collection of socket read/write statistics, default disabled */
225     NLboolean   nl_big_endian_data; /* is the packet data big endian? */
226 } nl_state_t;
227 
228 /* used by the drivers to allocate and free socket objects */
229 NLsocket nlGetNewSocket(void);
230 
231 /* other functions */
232 NLboolean nlGroupInit(void);
233 void nlGroupShutdown(void);
234 void nlGroupLock(void);
235 void nlGroupUnlock(void);
236 NLboolean nlGroupGetSocketsINT(NLint group, /*@out@*/ NLsocket *socket, /*@in@*/ NLint *number);
237 NLboolean nlIsValidSocket(NLsocket socket);
238 NLboolean nlLockSocket(NLsocket socket, NLint which);
239 void nlUnlockSocket(NLsocket socket, NLint which);
240 void nlSetError(NLenum err);
241 void nlThreadSleep(NLint mseconds);
242 
243 /* globals (as few as possible) */
244 extern volatile nl_state_t nlState;
245 
246 typedef /*@only@*/ nl_socket_t *pnl_socket_t;
247 extern /*@only@*/ pnl_socket_t *nlSockets;
248 
249 #ifdef __cplusplus
250 }  /* extern "C" */
251 #endif
252 
253 #endif /* INTERNAL_H */
254 
255