undns 0.4.0a
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/undns_decode +29 -0
- data/ext/undns/buffer.c +247 -0
- data/ext/undns/buffer.h +59 -0
- data/ext/undns/config.h +2 -0
- data/ext/undns/conventions.c +1813 -0
- data/ext/undns/conventions.h +89 -0
- data/ext/undns/conventlex.c +2808 -0
- data/ext/undns/earth.c +180 -0
- data/ext/undns/earth.h +4 -0
- data/ext/undns/exception.h +12 -0
- data/ext/undns/extconf.rb +44 -0
- data/ext/undns/filetest.c +90 -0
- data/ext/undns/filetest.h +7 -0
- data/ext/undns/hashes.c +104 -0
- data/ext/undns/hashes.h +48 -0
- data/ext/undns/hashtable.c +518 -0
- data/ext/undns/hashtable.h +103 -0
- data/ext/undns/my_ruby.h +3 -0
- data/ext/undns/nscommon.h +207 -0
- data/ext/undns/originAS.c +134 -0
- data/ext/undns/originAS.h +17 -0
- data/ext/undns/progress.c +285 -0
- data/ext/undns/progress.h +45 -0
- data/ext/undns/queue.c +346 -0
- data/ext/undns/queue.h +70 -0
- data/ext/undns/radix.c +517 -0
- data/ext/undns/radix.h +72 -0
- data/ext/undns/ruleset.c +603 -0
- data/ext/undns/ruleset.h +108 -0
- data/ext/undns/swig-undns_wrap-rb.c +2995 -0
- data/ext/undns/typed_hashtable.h +158 -0
- data/ext/undns/typed_queue.h +112 -0
- data/ext/undns/xmalloc.c +153 -0
- data/ext/undns/xmalloc.h +14 -0
- data/lib/undns.rb +5 -0
- metadata +84 -0
data/ext/undns/earth.c
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
#define _GNU_SOURCE
|
2
|
+
#include <config.h>
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <string.h>
|
6
|
+
#include <math.h>
|
7
|
+
#include <assert.h>
|
8
|
+
|
9
|
+
#ifdef HAVE_GNUREGEX_H
|
10
|
+
#include <gnuregex.h>
|
11
|
+
#else
|
12
|
+
#include <regex.h>
|
13
|
+
#endif
|
14
|
+
|
15
|
+
#include "xmalloc.h"
|
16
|
+
#include "nscommon.h"
|
17
|
+
#include "typed_hashtable.h"
|
18
|
+
|
19
|
+
struct location_table_entry {
|
20
|
+
char *place;
|
21
|
+
float latitude;
|
22
|
+
float longitude;
|
23
|
+
};
|
24
|
+
|
25
|
+
static unsigned int hash_lte(const struct location_table_entry *sbs) {
|
26
|
+
unsigned int ret;
|
27
|
+
const char *p;
|
28
|
+
for(ret=0, p=sbs->place; p!= NULL && *p!='\0'; p++)
|
29
|
+
ret += (unsigned int) *p;
|
30
|
+
return ret;
|
31
|
+
}
|
32
|
+
|
33
|
+
static boolean isequal_lte(const struct location_table_entry *sbs1,
|
34
|
+
const struct location_table_entry *sbs2) {
|
35
|
+
return( strcmp(sbs1->place, sbs2->place) == 0 );
|
36
|
+
}
|
37
|
+
|
38
|
+
DECLARE_TYPED_HASHTABLE(struct location_table_entry, lte);
|
39
|
+
|
40
|
+
lte_hashtable loctable;
|
41
|
+
|
42
|
+
/* load geo/LocationTable, which is a "'d place name, followed
|
43
|
+
by decimal latitude and longitude, may be negative (west or south) */
|
44
|
+
void init_earth(const char *LocationTableFilename) {
|
45
|
+
FILE *ltfp = fopen(LocationTableFilename, "r");
|
46
|
+
char regex[] = "^\"([^\"]+)\" *(-?[0-9\\.]+) *(-?[0-9\\.]+)";
|
47
|
+
char linebuf[255];
|
48
|
+
if(ltfp == NULL) {
|
49
|
+
printf("Unable to load %s as location table\n",
|
50
|
+
LocationTableFilename);
|
51
|
+
return;
|
52
|
+
}
|
53
|
+
#ifdef DEPRECATED_GNU_REGEX
|
54
|
+
re_syntax_options = RE_SYNTAX_POSIX_EGREP;
|
55
|
+
struct re_registers regs;
|
56
|
+
struct re_pattern_buffer rpbuf;
|
57
|
+
memset(&rpbuf, 0, sizeof(struct re_pattern_buffer));
|
58
|
+
{
|
59
|
+
const char *errstr =
|
60
|
+
re_compile_pattern(regex, strlen(regex), &rpbuf);
|
61
|
+
if (errstr != NULL) {
|
62
|
+
fprintf(stderr, "error in compiling regular expression: %s\n",
|
63
|
+
errstr);
|
64
|
+
return;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
regs.num_regs = REGS_UNALLOCATED;
|
68
|
+
#else
|
69
|
+
regex_t rpbuf;
|
70
|
+
#ifndef REGS_LEN
|
71
|
+
#define REGS_LEN 10
|
72
|
+
#endif
|
73
|
+
regmatch_t regs[REGS_LEN];
|
74
|
+
{
|
75
|
+
int error = regcomp(&rpbuf, regex, REG_EXTENDED);
|
76
|
+
if(error) {
|
77
|
+
char *err = malloc(256);
|
78
|
+
err[255]='\0';
|
79
|
+
regerror(error, &rpbuf, err, 255);
|
80
|
+
fprintf(stderr, "error in compiling regular expression '%s': %s\n", regex, err);
|
81
|
+
free(err);
|
82
|
+
return;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
#endif
|
86
|
+
/* todo - free lte's (not that it matters) */
|
87
|
+
loctable = lte_ht_new(200, hash_lte, isequal_lte, NULL);
|
88
|
+
|
89
|
+
while(fgets(linebuf,255,ltfp)) {
|
90
|
+
NEWPTRX(struct location_table_entry, newlte);
|
91
|
+
#ifdef DEPRECATED_GNU_REGEX
|
92
|
+
int matchedchars = re_match(&rpbuf, linebuf, strlen(linebuf), 0, ®s);
|
93
|
+
if (matchedchars <= 0) {
|
94
|
+
/* may be unnecessary to print this out to stderr. */
|
95
|
+
fprintf(stderr, "init_earth: Couldn't parse line: %s", linebuf);
|
96
|
+
free(newlte);
|
97
|
+
continue;
|
98
|
+
}
|
99
|
+
newlte->place = malloc(regs.end[1] - regs.start[1] + 1);
|
100
|
+
strncpy(newlte->place, linebuf+regs.start[1], regs.end[1]-regs.start[1]);
|
101
|
+
newlte->place[ regs.end[1] - regs.start[1] ] = '\0';
|
102
|
+
if(lte_ht_lookup(loctable, newlte) == NULL) {
|
103
|
+
newlte->latitude = atof(linebuf+regs.start[2]);
|
104
|
+
newlte->longitude = atof(linebuf+regs.start[3]);
|
105
|
+
lte_ht_insert(loctable, newlte);
|
106
|
+
} else {
|
107
|
+
free(newlte->place);
|
108
|
+
free(newlte);
|
109
|
+
}
|
110
|
+
#else
|
111
|
+
int reg_ret = regexec(&rpbuf, linebuf, REGS_LEN, regs, 0);
|
112
|
+
if(reg_ret == REG_NOMATCH) {
|
113
|
+
fprintf(stderr, "init_earth: Couldn't parse line: %s", linebuf);
|
114
|
+
free(newlte);
|
115
|
+
continue;
|
116
|
+
}
|
117
|
+
newlte->place = malloc(regs[1].rm_eo - regs[1].rm_so + 1);
|
118
|
+
strncpy(newlte->place, linebuf+regs[1].rm_so, regs[1].rm_eo-regs[1].rm_so);
|
119
|
+
newlte->place[ regs[1].rm_eo - regs[1].rm_so ] = '\0';
|
120
|
+
if(lte_ht_lookup(loctable, newlte) == NULL) {
|
121
|
+
newlte->latitude = atof(linebuf+regs[2].rm_so);
|
122
|
+
newlte->longitude = atof(linebuf+regs[3].rm_so);
|
123
|
+
lte_ht_insert(loctable, newlte);
|
124
|
+
} else {
|
125
|
+
free(newlte->place);
|
126
|
+
free(newlte);
|
127
|
+
}
|
128
|
+
#endif
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
#define PIOVER ((double)0.017453293)
|
133
|
+
/* in meters: */
|
134
|
+
#define RADIUS (6367000)
|
135
|
+
/* meters per second through glass */
|
136
|
+
/* according to http://www.play-hookey.com/optics/fiber5.html */
|
137
|
+
#define SOL (200000000)
|
138
|
+
|
139
|
+
/* calculate distance between places. replace +'s in
|
140
|
+
place names with spaces for lookup. */
|
141
|
+
double min_latency_seconds(const char *place1, const char *place2) {
|
142
|
+
struct location_table_entry lookup1;
|
143
|
+
struct location_table_entry lookup2;
|
144
|
+
struct location_table_entry *found1, *found2;
|
145
|
+
char *p;
|
146
|
+
|
147
|
+
assert(loctable != NULL);
|
148
|
+
|
149
|
+
lookup1.place = strdup(place1);
|
150
|
+
lookup2.place = strdup(place2);
|
151
|
+
assert(lookup1.place != NULL);
|
152
|
+
assert(lookup2.place != NULL);
|
153
|
+
|
154
|
+
for(p=lookup1.place; *p!='\0'; p++) if(*p=='+') *p = ' ';
|
155
|
+
for(p=lookup2.place; *p!='\0'; p++) if(*p=='+') *p = ' ';
|
156
|
+
|
157
|
+
found1 = lte_ht_lookup(loctable, &lookup1);
|
158
|
+
found2 = lte_ht_lookup(loctable, &lookup2);
|
159
|
+
|
160
|
+
free(lookup1.place);
|
161
|
+
free(lookup2.place);
|
162
|
+
|
163
|
+
if(found1 != NULL && found2 != NULL ) {
|
164
|
+
double lat1 = found1->latitude * PIOVER;
|
165
|
+
double lat2 = found2->latitude * PIOVER;
|
166
|
+
double lon1 = found1->longitude * PIOVER;
|
167
|
+
double lon2 = found2->longitude * PIOVER;
|
168
|
+
double sindlat = sin(( lat2 - lat1)/2.0);
|
169
|
+
double sindlon = sin(( lon2 - lon1)/2.0);
|
170
|
+
double a = sindlat * sindlat + cos(lat1) * cos(lat2) * sindlon * sindlon;
|
171
|
+
double c = 2.0 * atan2(sqrt(a), sqrt(1.0-a)) ;
|
172
|
+
double d = RADIUS * c;
|
173
|
+
// fprintf(stderr, "min_latency_seconds returning %5.3f\n", d/(double)SOL);
|
174
|
+
return (d / (double)SOL);
|
175
|
+
}
|
176
|
+
return(-1.0);
|
177
|
+
|
178
|
+
|
179
|
+
}
|
180
|
+
|
data/ext/undns/earth.h
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
/* wouldn't ordinarily use exceptions, but it seemed
|
3
|
+
useful for integration with the scripting languages.
|
4
|
+
These routines define the signature, exception.c is
|
5
|
+
only linked when requisite symbols aren't provided
|
6
|
+
by swig/the interpreter.
|
7
|
+
*/
|
8
|
+
void clear_exception(void);
|
9
|
+
void throw_exception(const char *msg);
|
10
|
+
const char *check_exception(void);
|
11
|
+
|
12
|
+
#define throw_void(m) { throw_exception(m); return; }
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
|
3
|
+
# this file is responsible for building a makefile that
|
4
|
+
# eventually builds the undns.so or undns.dylib extension.
|
5
|
+
|
6
|
+
puts "hello"
|
7
|
+
|
8
|
+
$defs.push("-DHAVE_CONFIG_H")
|
9
|
+
# if have_library('pthread', 'pthread_cond_init') then
|
10
|
+
$defs.push("-DHAVE_LIBPTHREAD")
|
11
|
+
# end
|
12
|
+
have_header('gnuregex.h')
|
13
|
+
have_header('stdint.h')
|
14
|
+
have_header('unistd.h')
|
15
|
+
have_header('error.h')
|
16
|
+
have_header('sys/types.h')
|
17
|
+
have_header('sys/time.h')
|
18
|
+
have_header('ruby/io.h')
|
19
|
+
have_func('snprintf')
|
20
|
+
$defs.push('-DPKGDATADIR=\"$(RUBYCOMMONDIR)\"')
|
21
|
+
$defs.push('-DONIG_ESCAPE_REGEX_T_COLLISION') # deep in there is a typedef
|
22
|
+
|
23
|
+
# create_header('config.h')
|
24
|
+
|
25
|
+
# CONFIG["DLDFLAGS"].gsub!(/multiply_definedsuppress/, 'multiply_defined suppress')
|
26
|
+
# CONFIG["LIBRUBY_DLDFLAGS"].gsub!(/multiply_definedsuppress/, 'multiply_defined suppress')
|
27
|
+
|
28
|
+
create_makefile('undns')
|
29
|
+
|
30
|
+
# since I develop on the busted mac; this fragment from
|
31
|
+
# Phusion Passenger.
|
32
|
+
if RUBY_PLATFORM =~ /darwin/
|
33
|
+
# The OS X Clang 503.0.38 update (circa March 15 2014)
|
34
|
+
# broke /usr/bin/ruby's mkmf. mkmf inserts
|
35
|
+
# -multiply_definedsuppress into the Makefile, but that
|
36
|
+
# flag is no longer supported by Clang. We remove this
|
37
|
+
# manually.
|
38
|
+
makefile = File.read("Makefile")
|
39
|
+
makefile.sub!(/-multiply_definedsuppress/, "")
|
40
|
+
File.open("Makefile", "w") do |f|
|
41
|
+
f.write(makefile)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#ifdef HAVE_CONFIG_H
|
2
|
+
#include <config.h>
|
3
|
+
#endif
|
4
|
+
#include <sys/types.h>
|
5
|
+
#include <sys/stat.h>
|
6
|
+
#include <sys/time.h>
|
7
|
+
#include <unistd.h>
|
8
|
+
#include <errno.h>
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <string.h>
|
11
|
+
#include "filetest.h"
|
12
|
+
|
13
|
+
boolean fileExists(const char *filename) {
|
14
|
+
struct stat s;
|
15
|
+
if(stat(filename,&s)== 0) {
|
16
|
+
if(S_ISREG(s.st_mode)) {
|
17
|
+
return TRUE;
|
18
|
+
/* } else {
|
19
|
+
printf("%s is not a regular file\n", filename); */
|
20
|
+
}
|
21
|
+
}
|
22
|
+
return FALSE;
|
23
|
+
}
|
24
|
+
boolean fileIsNewerThan(const char *filename, struct timeval *tv) {
|
25
|
+
struct stat s;
|
26
|
+
if(stat(filename,&s)== 0) {
|
27
|
+
// mac defines mtimespec, which is more precise, but doesn't
|
28
|
+
// appear universal.
|
29
|
+
if(s.st_mtime >= tv->tv_sec) {
|
30
|
+
return TRUE;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
return FALSE;
|
34
|
+
}
|
35
|
+
|
36
|
+
boolean dirExists(const char *dirname) {
|
37
|
+
struct stat s;
|
38
|
+
if(stat(dirname,&s)== 0) {
|
39
|
+
if(S_ISDIR(s.st_mode)) {
|
40
|
+
return TRUE;
|
41
|
+
/* } else {
|
42
|
+
printf("%s is not a directory\n", dirname); */
|
43
|
+
}
|
44
|
+
}
|
45
|
+
return FALSE;
|
46
|
+
}
|
47
|
+
|
48
|
+
/* acts like execvp, with code inspired by it */
|
49
|
+
/* mustfree */
|
50
|
+
/*@null@*/
|
51
|
+
char *searchPath(/*@null@*/ const char *path,
|
52
|
+
/*@notnull@ */ const char *find_me)
|
53
|
+
{
|
54
|
+
char *buf;
|
55
|
+
const char *p;
|
56
|
+
int len, pathlen;
|
57
|
+
if (path == NULL) return NULL;
|
58
|
+
/* if (strchr(find_me, '/') != NULL) { */
|
59
|
+
if (find_me[0] == '/' || find_me[0] == '.') {
|
60
|
+
return (strdup_ordie(find_me));
|
61
|
+
}
|
62
|
+
pathlen = strlen(path);
|
63
|
+
len = strlen(find_me) + 1;
|
64
|
+
buf = malloc_ordie(pathlen + len + 1);
|
65
|
+
memcpy(buf + pathlen + 1, find_me, len);
|
66
|
+
buf[pathlen] = '/';
|
67
|
+
|
68
|
+
for (p = path; p != NULL; path = p, path++) {
|
69
|
+
char *startp;
|
70
|
+
p = strchr(path, ':');
|
71
|
+
if (p == NULL) {
|
72
|
+
/* not found; p should point to the null char at the end */
|
73
|
+
startp =
|
74
|
+
memcpy(buf + pathlen - strlen(path), path, strlen(path));
|
75
|
+
} else if (p == path) {
|
76
|
+
/* double colon in a path apparently means try here */
|
77
|
+
startp = &buf[pathlen + 1];
|
78
|
+
} else {
|
79
|
+
/* copy the part between the colons to the buffer */
|
80
|
+
startp = memcpy(buf + pathlen - (p - path), path, p - path);
|
81
|
+
}
|
82
|
+
if (fileExists(startp) != 0) {
|
83
|
+
char *ret = strdup_ordie(startp);
|
84
|
+
free(buf);
|
85
|
+
return (ret);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
free(buf);
|
89
|
+
return (NULL);
|
90
|
+
}
|
data/ext/undns/hashes.c
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2002
|
3
|
+
* Neil Spring and the University of Washington.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions
|
8
|
+
* are met:
|
9
|
+
* 1. Redistributions of source code must retain the above copyright
|
10
|
+
* notice, this list of conditions and the following disclaimer.
|
11
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer in the
|
13
|
+
* documentation and/or other materials provided with the distribution.
|
14
|
+
* 3. The name of the author(s) may not be used to endorse or promote
|
15
|
+
* products derived from this software without specific prior
|
16
|
+
* written permission.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
19
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
20
|
+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
21
|
+
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
22
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
23
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
24
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
25
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
26
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
27
|
+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
*/
|
29
|
+
|
30
|
+
#ifdef HAVE_CONFIG_H
|
31
|
+
#include <config.h>
|
32
|
+
#endif
|
33
|
+
#include "nscommon.h"
|
34
|
+
#include <assert.h>
|
35
|
+
#include <stdlib.h>
|
36
|
+
#include <string.h>
|
37
|
+
#include <sys/types.h>
|
38
|
+
#include <sys/socket.h> /* AF_INET */
|
39
|
+
#ifdef WITH_DMALLOC
|
40
|
+
#include <dmalloc.h>
|
41
|
+
#endif
|
42
|
+
#include "hashes.h"
|
43
|
+
|
44
|
+
unsigned int mac_hash(const void *key) {
|
45
|
+
unsigned int retval; // this is a pretty damn useless hash.
|
46
|
+
const macaddress *mac1 = key;
|
47
|
+
retval=(unsigned int)(*mac1*1109); // prime.
|
48
|
+
return(retval);
|
49
|
+
}
|
50
|
+
|
51
|
+
// * uses key as a pointer *
|
52
|
+
unsigned int ip_hash(const void *key) {
|
53
|
+
const unsigned long *addr = key;
|
54
|
+
return(*addr*12917);
|
55
|
+
}
|
56
|
+
|
57
|
+
// * uses key as an integer *
|
58
|
+
unsigned int port_hash(const void *key) {
|
59
|
+
return((unsigned int)key);
|
60
|
+
}
|
61
|
+
|
62
|
+
unsigned int string_hash(const char *obj) {
|
63
|
+
unsigned int h= 0; // seed with the server.
|
64
|
+
unsigned int i;
|
65
|
+
assert(obj!=NULL);
|
66
|
+
for(i=0; i<256 && obj[i]!='\0'; i++){
|
67
|
+
h*=307;
|
68
|
+
h+=(unsigned int) obj[i];
|
69
|
+
}
|
70
|
+
return h;
|
71
|
+
}
|
72
|
+
unsigned int pstring_hash(const hash_cptr *key) {
|
73
|
+
return(string_hash(*key));
|
74
|
+
}
|
75
|
+
|
76
|
+
boolean mac_isequal(const void *v1, const void *v2) {
|
77
|
+
const macaddress *mac1 = v1;
|
78
|
+
const macaddress *mac2 = v2;
|
79
|
+
return((*mac1==*mac2) ? TRUE : FALSE);
|
80
|
+
}
|
81
|
+
boolean ip_isequal(const void *v1, const void *v2) {
|
82
|
+
const unsigned long *addr1 = v1;
|
83
|
+
const unsigned long *addr2 = v2;
|
84
|
+
return((*addr1==*addr2) ? TRUE : FALSE);
|
85
|
+
}
|
86
|
+
boolean port_isequal(const void *key1, const void *key2) {
|
87
|
+
return((key1==key2) ? TRUE : FALSE);
|
88
|
+
}
|
89
|
+
boolean string_isequal(const char *v1, const char *v2) {
|
90
|
+
return( (strcmp(v1,v2)==0) ? TRUE : FALSE);
|
91
|
+
}
|
92
|
+
boolean pstring_isequal(const hash_cptr *v1, const hash_cptr *v2) {
|
93
|
+
return(string_isequal(*v1, *v2));
|
94
|
+
}
|
95
|
+
|
96
|
+
boolean sockaddr_in_isequal(const struct sockaddr_in *v1, const struct sockaddr_in *v2) {
|
97
|
+
assert(v1->sin_family == AF_INET);
|
98
|
+
assert(v2->sin_family == AF_INET);
|
99
|
+
return ( v1->sin_port == v2->sin_port && memcmp(&v1->sin_addr, &v2->sin_addr, sizeof(struct in_addr)) == 0);
|
100
|
+
}
|
101
|
+
|
102
|
+
unsigned int sockaddr_in_hash(const struct sockaddr_in *v) {
|
103
|
+
return(v->sin_addr.s_addr*12917 + v->sin_port);
|
104
|
+
}
|