geoip2_c 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +3 -4
  3. data/README.md +21 -3
  4. data/docker-compose.yml +15 -1
  5. data/dockerfiles/{Dockerfile-ruby2.1 → Dockerfile-ruby2.5} +1 -1
  6. data/dockerfiles/{Dockerfile-ruby2.2 → Dockerfile-ruby2.6} +1 -1
  7. data/ext/geoip2/geoip2.c +5 -3
  8. data/ext/geoip2/libmaxminddb/.gitignore +3 -0
  9. data/ext/geoip2/libmaxminddb/.travis.yml +24 -2
  10. data/ext/geoip2/libmaxminddb/Changes.md +39 -0
  11. data/ext/geoip2/libmaxminddb/README.dev.md +41 -30
  12. data/ext/geoip2/libmaxminddb/README.md +3 -3
  13. data/ext/geoip2/libmaxminddb/bin/Makefile.am +5 -0
  14. data/ext/geoip2/libmaxminddb/bin/mmdblookup.c +333 -15
  15. data/ext/geoip2/libmaxminddb/configure.ac +5 -5
  16. data/ext/geoip2/libmaxminddb/dev-bin/ppa-release.sh +8 -5
  17. data/ext/geoip2/libmaxminddb/dev-bin/release.sh +7 -0
  18. data/ext/geoip2/libmaxminddb/dev-bin/valgrind-all.pl +10 -3
  19. data/ext/geoip2/libmaxminddb/include/maxminddb.h +11 -2
  20. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj +3 -1
  21. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj.filters +7 -1
  22. data/ext/geoip2/libmaxminddb/src/Makefile.am +18 -2
  23. data/ext/geoip2/libmaxminddb/src/data-pool.c +180 -0
  24. data/ext/geoip2/libmaxminddb/src/data-pool.h +52 -0
  25. data/ext/geoip2/libmaxminddb/src/maxminddb.c +58 -48
  26. data/ext/geoip2/libmaxminddb/t/Makefile.am +6 -2
  27. data/ext/geoip2/libmaxminddb/t/bad_databases_t.c +1 -0
  28. data/ext/geoip2/libmaxminddb/t/basic_lookup_t.c +35 -0
  29. data/ext/geoip2/libmaxminddb/t/data-pool-t.c +374 -0
  30. data/ext/geoip2/libmaxminddb/t/external_symbols_t.pl +106 -0
  31. data/lib/geoip2/version.rb +1 -1
  32. metadata +9 -7
  33. data/dockerfiles/Dockerfile-ruby2.3 +0 -8
@@ -2,7 +2,7 @@
2
2
  # Process this file with autoconf to produce a configure script.
3
3
 
4
4
  AC_PREREQ([2.63])
5
- AC_INIT([libmaxminddb], [1.2.1], [support@maxmind.com])
5
+ AC_INIT([libmaxminddb], [1.3.2], [support@maxmind.com])
6
6
  AC_CONFIG_SRCDIR([include/maxminddb.h])
7
7
  AC_CONFIG_HEADERS([config.h include/maxminddb_config.h])
8
8
 
@@ -63,9 +63,11 @@ AC_CHECK_HEADERS([arpa/inet.h assert.h fcntl.h inttypes.h libgen.h math.h netdb.
63
63
  # so we only run them on non MinGW-Systems. For MinGW we also need to link
64
64
  # against ws2_32.
65
65
  AC_CANONICAL_HOST
66
+ is_windows=false
66
67
  case $host_os in
67
68
  mingw*)
68
69
  LDFLAGS="-lws2_32"
70
+ is_windows=true
69
71
  ;;
70
72
  *)
71
73
  AC_TYPE_OFF_T
@@ -77,6 +79,7 @@ case $host_os in
77
79
  ;;
78
80
  esac
79
81
 
82
+ AM_CONDITIONAL([WINDOWS], [test x$is_windows = xtrue])
80
83
 
81
84
  # This check is backwards in order to make life easier for people writing
82
85
  # extensions in other languages that link to this library. If they want to
@@ -94,15 +97,12 @@ AC_CHECK_TYPE(
94
97
 
95
98
  AC_CHECK_TYPES([boolean])
96
99
 
97
- AC_CHECK_FUNC(
98
- [open_memstream],
99
- [AC_DEFINE([HAVE_OPEN_MEMSTREAM], [1], [Has an open_memstream() function])])
100
+ AC_CHECK_FUNCS([clock_gettime open_memstream])
100
101
 
101
102
  AC_C_BIGENDIAN(
102
103
  [AC_DEFINE([MMDB_LITTLE_ENDIAN], [0], [System is big-endian])],
103
104
  [AC_DEFINE([MMDB_LITTLE_ENDIAN], [1], [System is little-endian])])
104
105
 
105
- AC_FUNC_MALLOC
106
106
  AC_FUNC_MMAP
107
107
 
108
108
  AC_SEARCH_LIBS([fabs], [m])
@@ -4,7 +4,7 @@ set -e
4
4
  set -x
5
5
  set -u
6
6
 
7
- DISTS=( wily trusty precise )
7
+ DISTS=( artful zesty xenial trusty precise )
8
8
 
9
9
  VERSION=$(perl -MFile::Slurp::Tiny=read_file -MDateTime <<EOF
10
10
  use v5.16;
@@ -27,11 +27,11 @@ pushd "$SRCDIR"
27
27
  git merge "$VERSION"
28
28
 
29
29
  for dist in "${DISTS[@]}"; do
30
- git clean -xfd
31
- git reset HEAD --hard
32
-
33
30
  dch -v "$VERSION-0+maxmind1~$dist" -D "$dist" -u low "New upstream release."
34
31
  gbp buildpackage -S --git-ignore-new
32
+
33
+ git clean -xfd
34
+ git reset HEAD --hard
35
35
  done
36
36
 
37
37
  read -e -p "Release to PPA? (y/n)" SHOULD_RELEASE
@@ -41,9 +41,12 @@ if [ "$SHOULD_RELEASE" != "y" ]; then
41
41
  exit 1
42
42
  fi
43
43
 
44
+ # Upload to launchpad
44
45
  dput ppa:maxmind/ppa ../*source.changes
45
46
 
46
- popd
47
+ # Make the changelog up to date in git
48
+
49
+ dch -v "$VERSION-0+maxmind1" -D "${DISTS[0]}" -u low "New upstream release."
47
50
 
48
51
  git add debian/changelog
49
52
  git commit -m "Update debian/changelog for $VERSION"
@@ -47,6 +47,13 @@ if [ -n "$(git status --porcelain)" ]; then
47
47
  git commit -m "Bumped version to $version"
48
48
  fi
49
49
 
50
+ ./bootstrap
51
+ ./configure
52
+ make
53
+ make check
54
+ make clean
55
+ make safedist
56
+
50
57
  if [ ! -d .gh-pages ]; then
51
58
  echo "Checking out gh-pages in .gh-pages"
52
59
  git clone -b gh-pages git@github.com:maxmind/libmaxminddb.git .gh-pages
@@ -1,5 +1,10 @@
1
1
  #!/usr/bin/env perl
2
2
 
3
+ # Note to run this you will probably want to build with ./configure
4
+ # --disable-shared. You don't want to valgrind the libtool script.
5
+ #
6
+ # Also make sure you compile the tests first (`make check').
7
+
3
8
  use strict;
4
9
  use warnings;
5
10
 
@@ -11,11 +16,13 @@ my $top_dir = "$Bin/..";
11
16
 
12
17
  my $output;
13
18
 
14
- my @tests = glob "$top_dir/t/.libs/lt-*_t";
19
+ my @tests;
20
+ push @tests, glob "$top_dir/t/*_t";
21
+ push @tests, glob "$top_dir/t/*-t";
15
22
 
16
23
  my @mmdblookup = (
17
24
  "$top_dir/bin/mmdblookup",
18
- '--file', "$top_dir/maxmind-db/test-data/MaxMind-DB-test-decoder.mmdb",
25
+ '--file', "$top_dir/t/maxmind-db/test-data/MaxMind-DB-test-decoder.mmdb",
19
26
  '--ip',
20
27
  );
21
28
 
@@ -31,7 +38,7 @@ my @cmds = (
31
38
  for my $cmd (@cmds) {
32
39
  my $output;
33
40
  run3(
34
- [ qw( valgrind --leak-check=full -- ), @{$cmd} ],
41
+ [ qw( valgrind -v --leak-check=full --show-leak-kinds=all -- ), @{$cmd} ],
35
42
  \undef,
36
43
  \$output,
37
44
  \$output,
@@ -5,8 +5,16 @@ extern "C" {
5
5
  #ifndef MAXMINDDB_H
6
6
  #define MAXMINDDB_H
7
7
 
8
+ /* Request POSIX.1-2008. However, we want to remain compatible with
9
+ * POSIX.1-2001 (since we have been historically and see no reason to drop
10
+ * compatibility). By requesting POSIX.1-2008, we can conditionally use
11
+ * features provided by that standard if the implementation provides it. We can
12
+ * check for what the implementation provides by checking the _POSIX_VERSION
13
+ * macro after including unistd.h. If a feature is in POSIX.1-2008 but not
14
+ * POSIX.1-2001, check that macro before using the feature (or check for the
15
+ * feature directly if possible). */
8
16
  #ifndef _POSIX_C_SOURCE
9
- #define _POSIX_C_SOURCE 200112L
17
+ #define _POSIX_C_SOURCE 200809L
10
18
  #endif
11
19
 
12
20
  #include "maxminddb_config.h"
@@ -20,7 +28,7 @@ extern "C" {
20
28
  #include <winsock2.h>
21
29
  #include <ws2tcpip.h>
22
30
  /* libmaxminddb package version from configure */
23
- #define PACKAGE_VERSION "1.2.1"
31
+ #define PACKAGE_VERSION "1.3.2"
24
32
 
25
33
  typedef ADDRESS_FAMILY sa_family_t;
26
34
 
@@ -135,6 +143,7 @@ typedef struct MMDB_entry_data_s {
135
143
  typedef struct MMDB_entry_data_list_s {
136
144
  MMDB_entry_data_s entry_data;
137
145
  struct MMDB_entry_data_list_s *next;
146
+ void *pool;
138
147
  } MMDB_entry_data_list_s;
139
148
 
140
149
  typedef struct MMDB_description_s {
@@ -20,9 +20,11 @@
20
20
  </ItemGroup>
21
21
  <ItemGroup>
22
22
  <ClCompile Include="..\..\src\maxminddb.c" />
23
+ <ClCompile Include="..\..\src\data-pool.c" />
23
24
  </ItemGroup>
24
25
  <ItemGroup>
25
26
  <ClInclude Include="..\..\include\maxminddb.h" />
27
+ <ClInclude Include="..\..\src\data-pool.h" />
26
28
  </ItemGroup>
27
29
  <ItemGroup>
28
30
  <None Include="README" />
@@ -138,4 +140,4 @@
138
140
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
139
141
  <ImportGroup Label="ExtensionTargets">
140
142
  </ImportGroup>
141
- </Project>
143
+ </Project>
@@ -14,13 +14,19 @@
14
14
  <ClCompile Include="..\..\src\maxminddb.c">
15
15
  <Filter>Source Files</Filter>
16
16
  </ClCompile>
17
+ <ClCompile Include="..\..\src\data-pool.c">
18
+ <Filter>Source Files</Filter>
19
+ </ClCompile>
17
20
  </ItemGroup>
18
21
  <ItemGroup>
19
22
  <ClInclude Include="..\..\include\maxminddb.h">
20
23
  <Filter>Header Files</Filter>
21
24
  </ClInclude>
25
+ <ClInclude Include="..\..\src\data-pool.h">
26
+ <Filter>Header Files</Filter>
27
+ </ClInclude>
22
28
  </ItemGroup>
23
29
  <ItemGroup>
24
30
  <None Include="README" />
25
31
  </ItemGroup>
26
- </Project>
32
+ </Project>
@@ -2,8 +2,24 @@ include $(top_srcdir)/common.mk
2
2
 
3
3
  lib_LTLIBRARIES = libmaxminddb.la
4
4
 
5
- libmaxminddb_la_SOURCES = maxminddb.c maxminddb-compat-util.h
6
- libmaxminddb_la_LDFLAGS = -version-info 0:7:0
5
+ libmaxminddb_la_SOURCES = maxminddb.c maxminddb-compat-util.h \
6
+ data-pool.c data-pool.h
7
+ libmaxminddb_la_LDFLAGS = -version-info 0:7:0 -export-symbols-regex '^MMDB_.*'
7
8
  include_HEADERS = $(top_srcdir)/include/maxminddb.h
8
9
 
9
10
  pkgconfig_DATA = libmaxminddb.pc
11
+
12
+ TESTS = test-data-pool
13
+
14
+ check_PROGRAMS = test-data-pool
15
+
16
+ test_data_pool_SOURCES = data-pool.c data-pool.h
17
+ test_data_pool_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/t -DTEST_DATA_POOL
18
+ test_data_pool_LDADD = $(top_srcdir)/t/libmmdbtest.la \
19
+ $(top_srcdir)/t/libtap/libtap.a
20
+
21
+ $(top_srcdir)/t/libmmdbtest.la:
22
+ $(MAKE) -C $(top_srcdir)/t libmmdbtest.la
23
+
24
+ $(top_srcdir)/t/libtap/libtap.a:
25
+ $(MAKE) -C $(top_srcdir)/t/libtap libtap.a
@@ -0,0 +1,180 @@
1
+ #include "data-pool.h"
2
+ #include "maxminddb.h"
3
+
4
+ #include <stdbool.h>
5
+ #include <stddef.h>
6
+ #include <stdlib.h>
7
+
8
+ static bool can_multiply(size_t const, size_t const, size_t const);
9
+
10
+ // Allocate an MMDB_data_pool_s. It initially has space for size
11
+ // MMDB_entry_data_list_s structs.
12
+ MMDB_data_pool_s *data_pool_new(size_t const size)
13
+ {
14
+ MMDB_data_pool_s *const pool = calloc(1, sizeof(MMDB_data_pool_s));
15
+ if (!pool) {
16
+ return NULL;
17
+ }
18
+
19
+ if (size == 0 ||
20
+ !can_multiply(SIZE_MAX, size, sizeof(MMDB_entry_data_list_s))) {
21
+ data_pool_destroy(pool);
22
+ return NULL;
23
+ }
24
+ pool->size = size;
25
+ pool->blocks[0] = calloc(pool->size, sizeof(MMDB_entry_data_list_s));
26
+ if (!pool->blocks[0]) {
27
+ data_pool_destroy(pool);
28
+ return NULL;
29
+ }
30
+ pool->blocks[0]->pool = pool;
31
+
32
+ pool->sizes[0] = size;
33
+
34
+ pool->block = pool->blocks[0];
35
+
36
+ return pool;
37
+ }
38
+
39
+ // Determine if we can multiply m*n. We can do this if the result will be below
40
+ // the given max. max will typically be SIZE_MAX.
41
+ //
42
+ // We want to know if we'll wrap around.
43
+ static bool can_multiply(size_t const max, size_t const m, size_t const n)
44
+ {
45
+ if (m == 0) {
46
+ return false;
47
+ }
48
+
49
+ return n <= max / m;
50
+ }
51
+
52
+ // Clean up the data pool.
53
+ void data_pool_destroy(MMDB_data_pool_s *const pool)
54
+ {
55
+ if (!pool) {
56
+ return;
57
+ }
58
+
59
+ for (size_t i = 0; i <= pool->index; i++) {
60
+ free(pool->blocks[i]);
61
+ }
62
+
63
+ free(pool);
64
+ }
65
+
66
+ // Claim a new struct from the pool. Doing this may cause the pool's size to
67
+ // grow.
68
+ MMDB_entry_data_list_s *data_pool_alloc(MMDB_data_pool_s *const pool)
69
+ {
70
+ if (!pool) {
71
+ return NULL;
72
+ }
73
+
74
+ if (pool->used < pool->size) {
75
+ MMDB_entry_data_list_s *const element = pool->block + pool->used;
76
+ pool->used++;
77
+ return element;
78
+ }
79
+
80
+ // Take it from a new block of memory.
81
+
82
+ size_t const new_index = pool->index + 1;
83
+ if (new_index == DATA_POOL_NUM_BLOCKS) {
84
+ // See the comment about not growing this on DATA_POOL_NUM_BLOCKS.
85
+ return NULL;
86
+ }
87
+
88
+ if (!can_multiply(SIZE_MAX, pool->size, 2)) {
89
+ return NULL;
90
+ }
91
+ size_t const new_size = pool->size * 2;
92
+
93
+ if (!can_multiply(SIZE_MAX, new_size, sizeof(MMDB_entry_data_list_s))) {
94
+ return NULL;
95
+ }
96
+ pool->blocks[new_index] = calloc(new_size, sizeof(MMDB_entry_data_list_s));
97
+ if (!pool->blocks[new_index]) {
98
+ return NULL;
99
+ }
100
+
101
+ // We don't need to set this, but it's useful for introspection in tests.
102
+ pool->blocks[new_index]->pool = pool;
103
+
104
+ pool->index = new_index;
105
+ pool->block = pool->blocks[pool->index];
106
+
107
+ pool->size = new_size;
108
+ pool->sizes[pool->index] = pool->size;
109
+
110
+ MMDB_entry_data_list_s *const element = pool->block;
111
+ pool->used = 1;
112
+ return element;
113
+ }
114
+
115
+ // Turn the structs in the array-like pool into a linked list.
116
+ //
117
+ // Before calling this function, the list isn't linked up.
118
+ MMDB_entry_data_list_s *data_pool_to_list(MMDB_data_pool_s *const pool)
119
+ {
120
+ if (!pool) {
121
+ return NULL;
122
+ }
123
+
124
+ if (pool->index == 0 && pool->used == 0) {
125
+ return NULL;
126
+ }
127
+
128
+ for (size_t i = 0; i <= pool->index; i++) {
129
+ MMDB_entry_data_list_s *const block = pool->blocks[i];
130
+
131
+ size_t size = pool->sizes[i];
132
+ if (i == pool->index) {
133
+ size = pool->used;
134
+ }
135
+
136
+ for (size_t j = 0; j < size - 1; j++) {
137
+ MMDB_entry_data_list_s *const cur = block + j;
138
+ cur->next = block + j + 1;
139
+ }
140
+
141
+ if (i < pool->index) {
142
+ MMDB_entry_data_list_s *const last = block + size - 1;
143
+ last->next = pool->blocks[i + 1];
144
+ }
145
+ }
146
+
147
+ return pool->blocks[0];
148
+ }
149
+
150
+ #ifdef TEST_DATA_POOL
151
+
152
+ #include <libtap/tap.h>
153
+ #include <maxminddb_test_helper.h>
154
+
155
+ static void test_can_multiply(void);
156
+
157
+ int main(void)
158
+ {
159
+ plan(NO_PLAN);
160
+ test_can_multiply();
161
+ done_testing();
162
+ }
163
+
164
+ static void test_can_multiply(void)
165
+ {
166
+ {
167
+ ok(can_multiply(SIZE_MAX, 1, SIZE_MAX), "1*SIZE_MAX is ok");
168
+ }
169
+
170
+ {
171
+ ok(!can_multiply(SIZE_MAX, 2, SIZE_MAX), "2*SIZE_MAX is not ok");
172
+ }
173
+
174
+ {
175
+ ok(can_multiply(SIZE_MAX, 10240, sizeof(MMDB_entry_data_list_s)),
176
+ "1024 entry_data_list_s's are okay");
177
+ }
178
+ }
179
+
180
+ #endif
@@ -0,0 +1,52 @@
1
+ #ifndef DATA_POOL_H
2
+ #define DATA_POOL_H
3
+
4
+ #include "maxminddb.h"
5
+
6
+ #include <stdbool.h>
7
+ #include <stddef.h>
8
+
9
+ // This should be large enough that we never need to grow the array of pointers
10
+ // to blocks. 32 is enough. Even starting out of with size 1 (1 struct), the
11
+ // 32nd element alone will provide 2**32 structs as we exponentially increase
12
+ // the number in each block. Being confident that we do not have to grow the
13
+ // array lets us avoid writing code to do that. That code would be risky as it
14
+ // would rarely be hit and likely not be well tested.
15
+ #define DATA_POOL_NUM_BLOCKS 32
16
+
17
+ // A pool of memory for MMDB_entry_data_list_s structs. This is so we can
18
+ // allocate multiple up front rather than one at a time for performance
19
+ // reasons.
20
+ //
21
+ // The order you add elements to it (by calling data_pool_alloc()) ends up as
22
+ // the order of the list.
23
+ //
24
+ // The memory only grows. There is no support for releasing an element you take
25
+ // back to the pool.
26
+ typedef struct MMDB_data_pool_s {
27
+ // Index of the current block we're allocating out of.
28
+ size_t index;
29
+
30
+ // The size of the current block, counting by structs.
31
+ size_t size;
32
+
33
+ // How many used in the current block, counting by structs.
34
+ size_t used;
35
+
36
+ // The current block we're allocating out of.
37
+ MMDB_entry_data_list_s *block;
38
+
39
+ // The size of each block.
40
+ size_t sizes[DATA_POOL_NUM_BLOCKS];
41
+
42
+ // An array of pointers to blocks of memory holding space for list
43
+ // elements.
44
+ MMDB_entry_data_list_s *blocks[DATA_POOL_NUM_BLOCKS];
45
+ } MMDB_data_pool_s;
46
+
47
+ MMDB_data_pool_s *data_pool_new(size_t const);
48
+ void data_pool_destroy(MMDB_data_pool_s *const);
49
+ MMDB_entry_data_list_s *data_pool_alloc(MMDB_data_pool_s *const);
50
+ MMDB_entry_data_list_s *data_pool_to_list(MMDB_data_pool_s *const);
51
+
52
+ #endif