undns 0.4.0a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|