geoip2_c 0.3.2 → 0.3.3

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.
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