groupsock/inet.c

Go to the documentation of this file.
00001 #ifndef _NET_COMMON_H
00002 #include "NetCommon.h"
00003 #endif
00004 
00005 #include <stdio.h>
00006 
00007 #ifdef VXWORKS
00008 #include <inetLib.h>
00009 #endif
00010 
00011 /* Some systems (e.g., SunOS) have header files that erroneously declare inet_addr() as taking no arguments.
00012  * This confuses C++.  To overcome this, we use our own routine, implemented in C.
00013  */
00014 
00015 unsigned our_inet_addr(cp)
00016         char const* cp;
00017 {
00018         return inet_addr(cp);
00019 }
00020 
00021 #if defined(__WIN32__) || defined(_WIN32)
00022 #ifndef IMN_PIM
00023 #define WS_VERSION_CHOICE1 0x202/*MAKEWORD(2,2)*/
00024 #define WS_VERSION_CHOICE2 0x101/*MAKEWORD(1,1)*/
00025 int initializeWinsockIfNecessary(void) {
00026         /* We need to call an initialization routine before
00027          * we can do anything with winsock.  (How fucking lame!):
00028          */
00029         static int _haveInitializedWinsock = 0;
00030         WSADATA wsadata;
00031 
00032         if (!_haveInitializedWinsock) {
00033                 if ((WSAStartup(WS_VERSION_CHOICE1, &wsadata) != 0)
00034                     && ((WSAStartup(WS_VERSION_CHOICE2, &wsadata)) != 0)) {
00035                         return 0; /* error in initialization */
00036                 }
00037                 if ((wsadata.wVersion != WS_VERSION_CHOICE1)
00038                     && (wsadata.wVersion != WS_VERSION_CHOICE2)) {
00039                         WSACleanup();
00040                                 return 0; /* desired Winsock version was not available */
00041                 }
00042                 _haveInitializedWinsock = 1;
00043         }
00044 
00045         return 1;
00046 }
00047 #else
00048 int initializeWinsockIfNecessary(void) { return 1; }
00049 #endif
00050 #else
00051 #define initializeWinsockIfNecessary() 1
00052 #endif
00053 
00054 #ifndef NULL
00055 #define NULL 0
00056 #endif
00057 
00058 #ifdef USE_SYSTEM_RANDOM
00059 /* Use the system-supplied "random()" and "srandom()" functions */
00060 #include <stdlib.h>
00061 long our_random() {
00062 #if defined(__WIN32__) || defined(_WIN32)
00063   return rand();
00064 #else
00065   return random();
00066 #endif
00067 }
00068 void our_srandom(unsigned int x) {
00069 #if defined(__WIN32__) || defined(_WIN32)
00070   srand(x);
00071 #else
00072   srandom(x);
00073 #endif
00074 }
00075 
00076 #else
00077 
00078 /* Use our own implementation of the "random()" and "srandom()" functions */
00079 /*
00080  * random.c:
00081  *
00082  * An improved random number generation package.  In addition to the standard
00083  * rand()/srand() like interface, this package also has a special state info
00084  * interface.  The our_initstate() routine is called with a seed, an array of
00085  * bytes, and a count of how many bytes are being passed in; this array is
00086  * then initialized to contain information for random number generation with
00087  * that much state information.  Good sizes for the amount of state
00088  * information are 32, 64, 128, and 256 bytes.  The state can be switched by
00089  * calling the our_setstate() routine with the same array as was initiallized
00090  * with our_initstate().  By default, the package runs with 128 bytes of state
00091  * information and generates far better random numbers than a linear
00092  * congruential generator.  If the amount of state information is less than
00093  * 32 bytes, a simple linear congruential R.N.G. is used.
00094  *
00095  * Internally, the state information is treated as an array of longs; the
00096  * zeroeth element of the array is the type of R.N.G. being used (small
00097  * integer); the remainder of the array is the state information for the
00098  * R.N.G.  Thus, 32 bytes of state information will give 7 longs worth of
00099  * state information, which will allow a degree seven polynomial.  (Note:
00100  * the zeroeth word of state information also has some other information
00101  * stored in it -- see our_setstate() for details).
00102  *
00103  * The random number generation technique is a linear feedback shift register
00104  * approach, employing trinomials (since there are fewer terms to sum up that
00105  * way).  In this approach, the least significant bit of all the numbers in
00106  * the state table will act as a linear feedback shift register, and will
00107  * have period 2^deg - 1 (where deg is the degree of the polynomial being
00108  * used, assuming that the polynomial is irreducible and primitive).  The
00109  * higher order bits will have longer periods, since their values are also
00110  * influenced by pseudo-random carries out of the lower bits.  The total
00111  * period of the generator is approximately deg*(2**deg - 1); thus doubling
00112  * the amount of state information has a vast influence on the period of the
00113  * generator.  Note: the deg*(2**deg - 1) is an approximation only good for
00114  * large deg, when the period of the shift register is the dominant factor.
00115  * With deg equal to seven, the period is actually much longer than the
00116  * 7*(2**7 - 1) predicted by this formula.
00117  */
00118 
00119 /*
00120  * For each of the currently supported random number generators, we have a
00121  * break value on the amount of state information (you need at least this
00122  * many bytes of state info to support this random number generator), a degree
00123  * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
00124  * the separation between the two lower order coefficients of the trinomial.
00125  */
00126 #define TYPE_0          0               /* linear congruential */
00127 #define BREAK_0         8
00128 #define DEG_0           0
00129 #define SEP_0           0
00130 
00131 #define TYPE_1          1               /* x**7 + x**3 + 1 */
00132 #define BREAK_1         32
00133 #define DEG_1           7
00134 #define SEP_1           3
00135 
00136 #define TYPE_2          2               /* x**15 + x + 1 */
00137 #define BREAK_2         64
00138 #define DEG_2           15
00139 #define SEP_2           1
00140 
00141 #define TYPE_3          3               /* x**31 + x**3 + 1 */
00142 #define BREAK_3         128
00143 #define DEG_3           31
00144 #define SEP_3           3
00145 
00146 #define TYPE_4          4               /* x**63 + x + 1 */
00147 #define BREAK_4         256
00148 #define DEG_4           63
00149 #define SEP_4           1
00150 
00151 /*
00152  * Array versions of the above information to make code run faster --
00153  * relies on fact that TYPE_i == i.
00154  */
00155 #define MAX_TYPES       5               /* max number of types above */
00156 
00157 static int const degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
00158 static int const seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
00159 
00160 /*
00161  * Initially, everything is set up as if from:
00162  *
00163  *      our_initstate(1, &randtbl, 128);
00164  *
00165  * Note that this initialization takes advantage of the fact that srandom()
00166  * advances the front and rear pointers 10*rand_deg times, and hence the
00167  * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
00168  * element of the state information, which contains info about the current
00169  * position of the rear pointer is just
00170  *
00171  *      MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
00172  */
00173 
00174 static long randtbl[DEG_3 + 1] = {
00175         TYPE_3,
00176         0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
00177         0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
00178         0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
00179         0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
00180         0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
00181         0x27fb47b9,
00182 };
00183 
00184 /*
00185  * fptr and rptr are two pointers into the state info, a front and a rear
00186  * pointer.  These two pointers are always rand_sep places aparts, as they
00187  * cycle cyclically through the state information.  (Yes, this does mean we
00188  * could get away with just one pointer, but the code for random() is more
00189  * efficient this way).  The pointers are left positioned as they would be
00190  * from the call
00191  *
00192  *      our_initstate(1, randtbl, 128);
00193  *
00194  * (The position of the rear pointer, rptr, is really 0 (as explained above
00195  * in the initialization of randtbl) because the state table pointer is set
00196  * to point to randtbl[1] (as explained below).
00197  */
00198 static long* fptr = &randtbl[SEP_3 + 1];
00199 static long* rptr = &randtbl[1];
00200 
00201 /*
00202  * The following things are the pointer to the state information table, the
00203  * type of the current generator, the degree of the current polynomial being
00204  * used, and the separation between the two pointers.  Note that for efficiency
00205  * of random(), we remember the first location of the state information, not
00206  * the zeroeth.  Hence it is valid to access state[-1], which is used to
00207  * store the type of the R.N.G.  Also, we remember the last location, since
00208  * this is more efficient than indexing every time to find the address of
00209  * the last element to see if the front and rear pointers have wrapped.
00210  */
00211 static long *state = &randtbl[1];
00212 static int rand_type = TYPE_3;
00213 static int rand_deg = DEG_3;
00214 static int rand_sep = SEP_3;
00215 static long* end_ptr = &randtbl[DEG_3 + 1];
00216 
00217 /*
00218  * srandom:
00219  *
00220  * Initialize the random number generator based on the given seed.  If the
00221  * type is the trivial no-state-information type, just remember the seed.
00222  * Otherwise, initializes state[] based on the given "seed" via a linear
00223  * congruential generator.  Then, the pointers are set to known locations
00224  * that are exactly rand_sep places apart.  Lastly, it cycles the state
00225  * information a given number of times to get rid of any initial dependencies
00226  * introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
00227  * for default usage relies on values produced by this routine.
00228  */
00229 long our_random(void); /*forward*/
00230 void
00231 our_srandom(unsigned int x)
00232 {
00233         register int i;
00234 
00235         if (rand_type == TYPE_0)
00236                 state[0] = x;
00237         else {
00238                 state[0] = x;
00239                 for (i = 1; i < rand_deg; i++)
00240                         state[i] = 1103515245 * state[i - 1] + 12345;
00241                 fptr = &state[rand_sep];
00242                 rptr = &state[0];
00243                 for (i = 0; i < 10 * rand_deg; i++)
00244                         (void)our_random();
00245         }
00246 }
00247 
00248 /*
00249  * our_initstate:
00250  *
00251  * Initialize the state information in the given array of n bytes for future
00252  * random number generation.  Based on the number of bytes we are given, and
00253  * the break values for the different R.N.G.'s, we choose the best (largest)
00254  * one we can and set things up for it.  srandom() is then called to
00255  * initialize the state information.
00256  *
00257  * Note that on return from srandom(), we set state[-1] to be the type
00258  * multiplexed with the current value of the rear pointer; this is so
00259  * successive calls to our_initstate() won't lose this information and will be
00260  * able to restart with our_setstate().
00261  *
00262  * Note: the first thing we do is save the current state, if any, just like
00263  * our_setstate() so that it doesn't matter when our_initstate is called.
00264  *
00265  * Returns a pointer to the old state.
00266  */
00267 char *
00268 our_initstate(seed, arg_state, n)
00269         unsigned int seed;              /* seed for R.N.G. */
00270         char *arg_state;                /* pointer to state array */
00271         int n;                          /* # bytes of state info */
00272 {
00273         register char *ostate = (char *)(&state[-1]);
00274 
00275         if (rand_type == TYPE_0)
00276                 state[-1] = rand_type;
00277         else
00278                 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
00279         if (n < BREAK_0) {
00280 #ifdef DEBUG
00281                 (void)fprintf(stderr,
00282                     "random: not enough state (%d bytes); ignored.\n", n);
00283 #endif
00284                 return(0);
00285         }
00286         if (n < BREAK_1) {
00287                 rand_type = TYPE_0;
00288                 rand_deg = DEG_0;
00289                 rand_sep = SEP_0;
00290         } else if (n < BREAK_2) {
00291                 rand_type = TYPE_1;
00292                 rand_deg = DEG_1;
00293                 rand_sep = SEP_1;
00294         } else if (n < BREAK_3) {
00295                 rand_type = TYPE_2;
00296                 rand_deg = DEG_2;
00297                 rand_sep = SEP_2;
00298         } else if (n < BREAK_4) {
00299                 rand_type = TYPE_3;
00300                 rand_deg = DEG_3;
00301                 rand_sep = SEP_3;
00302         } else {
00303                 rand_type = TYPE_4;
00304                 rand_deg = DEG_4;
00305                 rand_sep = SEP_4;
00306         }
00307         state = &(((long *)arg_state)[1]);      /* first location */
00308         end_ptr = &state[rand_deg];     /* must set end_ptr before srandom */
00309         our_srandom(seed);
00310         if (rand_type == TYPE_0)
00311                 state[-1] = rand_type;
00312         else
00313                 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
00314         return(ostate);
00315 }
00316 
00317 /*
00318  * our_setstate:
00319  *
00320  * Restore the state from the given state array.
00321  *
00322  * Note: it is important that we also remember the locations of the pointers
00323  * in the current state information, and restore the locations of the pointers
00324  * from the old state information.  This is done by multiplexing the pointer
00325  * location into the zeroeth word of the state information.
00326  *
00327  * Note that due to the order in which things are done, it is OK to call
00328  * our_setstate() with the same state as the current state.
00329  *
00330  * Returns a pointer to the old state information.
00331  */
00332 char *
00333 our_setstate(arg_state)
00334         char *arg_state;
00335 {
00336         register long *new_state = (long *)arg_state;
00337         register int type = new_state[0] % MAX_TYPES;
00338         register int rear = new_state[0] / MAX_TYPES;
00339         char *ostate = (char *)(&state[-1]);
00340 
00341         if (rand_type == TYPE_0)
00342                 state[-1] = rand_type;
00343         else
00344                 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
00345         switch(type) {
00346         case TYPE_0:
00347         case TYPE_1:
00348         case TYPE_2:
00349         case TYPE_3:
00350         case TYPE_4:
00351                 rand_type = type;
00352                 rand_deg = degrees[type];
00353                 rand_sep = seps[type];
00354                 break;
00355         default:
00356 #ifdef DEBUG
00357                 (void)fprintf(stderr,
00358                     "random: state info corrupted; not changed.\n");
00359 #endif
00360                 break;
00361         }
00362         state = &new_state[1];
00363         if (rand_type != TYPE_0) {
00364                 rptr = &state[rear];
00365                 fptr = &state[(rear + rand_sep) % rand_deg];
00366         }
00367         end_ptr = &state[rand_deg];             /* set end_ptr too */
00368         return(ostate);
00369 }
00370 
00371 /*
00372  * random:
00373  *
00374  * If we are using the trivial TYPE_0 R.N.G., just do the old linear
00375  * congruential bit.  Otherwise, we do our fancy trinomial stuff, which is
00376  * the same in all the other cases due to all the global variables that have
00377  * been set up.  The basic operation is to add the number at the rear pointer
00378  * into the one at the front pointer.  Then both pointers are advanced to
00379  * the next location cyclically in the table.  The value returned is the sum
00380  * generated, reduced to 31 bits by throwing away the "least random" low bit.
00381  *
00382  * Note: the code takes advantage of the fact that both the front and
00383  * rear pointers can't wrap on the same call by not testing the rear
00384  * pointer if the front one has wrapped.
00385  *
00386  * Returns a 31-bit random number.
00387  */
00388 long our_random() {
00389   long i;
00390 
00391   if (rand_type == TYPE_0) {
00392     i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
00393   } else {
00394     /* Make copies of "rptr" and "fptr" before working with them, in case we're being called concurrently by multiple threads: */
00395     long* rp = rptr;
00396     long* fp = fptr;
00397 
00398     /* Make sure "rp" and "fp" are separated by the correct distance (again, allowing for concurrent access): */
00399     if (!(fp == rp+SEP_3 || fp+DEG_3 == rp+SEP_3)) {
00400       /* A rare case that should occur only if we're being called concurrently by multiple threads. */
00401       /* Restore the proper separation between the pointers: */
00402       if (rp <= fp) rp = fp-SEP_3; else rp = fp+DEG_3-SEP_3;
00403     }
00404 
00405     *fp += *rp;
00406     i = (*fp >> 1) & 0x7fffffff;        /* chucking least random bit */
00407     if (++fp >= end_ptr) {
00408       fp = state;
00409       ++rp;
00410     } else if (++rp >= end_ptr) {
00411       rp = state;
00412     }
00413 
00414     /* Restore "rptr" and "fptr" from our working copies: */
00415     rptr = rp;
00416     fptr = fp;
00417   }
00418 
00419   return i;
00420 }
00421 #endif
00422 
00423 u_int32_t our_random32() {
00424   /* Return a 32-bit random number.
00425      Because "our_random()" returns a 31-bit random number, we call it a second
00426      time, to generate the high bit.
00427      (Actually, to increase the likelhood of randomness, we take the middle 16 bits of two successive calls to "our_random()")
00428   */
00429   long random_1 = our_random();
00430   u_int32_t random16_1 = (u_int32_t)(random_1&0x00FFFF00);
00431 
00432   long random_2 = our_random();
00433   u_int32_t random16_2 = (u_int32_t)(random_2&0x00FFFF00);
00434 
00435   return (random16_1<<8) | (random16_2>>8);
00436 }
00437 
00438 #ifdef USE_OUR_BZERO
00439 #ifndef __bzero
00440 void
00441 __bzero (to, count)
00442   char *to;
00443   int count;
00444 {
00445   while (count-- > 0)
00446     {
00447       *to++ = 0;
00448     }
00449 }             
00450 #endif
00451 #endif

Generated on Wed Apr 23 16:11:59 2014 for live by  doxygen 1.5.2