mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Add maxmind to redbean
This commit is contained in:
parent
af645fcbec
commit
c371db6663
11 changed files with 2457 additions and 2 deletions
1
Makefile
1
Makefile
|
@ -138,6 +138,7 @@ include third_party/third_party.mk
|
||||||
include libc/testlib/testlib.mk
|
include libc/testlib/testlib.mk
|
||||||
include tool/viz/lib/vizlib.mk
|
include tool/viz/lib/vizlib.mk
|
||||||
include third_party/linenoise/linenoise.mk
|
include third_party/linenoise/linenoise.mk
|
||||||
|
include third_party/maxmind/maxmind.mk
|
||||||
include third_party/lua/lua.mk
|
include third_party/lua/lua.mk
|
||||||
include third_party/make/make.mk
|
include third_party/make/make.mk
|
||||||
include third_party/argon2/argon2.mk
|
include third_party/argon2/argon2.mk
|
||||||
|
|
13
third_party/maxmind/README.cosmo
vendored
Normal file
13
third_party/maxmind/README.cosmo
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
ORIGIN
|
||||||
|
|
||||||
|
git@github.com:maxmind/libmaxminddb.git
|
||||||
|
commit d918412fe7d514108d01e346a832d51e5ccf83c0
|
||||||
|
Author: Will Storey <wstorey@maxmind.com>
|
||||||
|
Date: Thu Apr 29 11:53:54 2021 -0700
|
||||||
|
Merge pull request #265 from maxmind/greg/release
|
||||||
|
1.6.0
|
||||||
|
|
||||||
|
LOCAL CHANGES
|
||||||
|
|
||||||
|
- Added MMDB_lookup()
|
||||||
|
- Remove Berkeleyisms from API design w.r.t. IPs.
|
257
third_party/maxmind/getmetroname.c
vendored
Normal file
257
third_party/maxmind/getmetroname.c
vendored
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "third_party/maxmind/maxminddb.h"
|
||||||
|
|
||||||
|
const struct thatispacked MetroName {
|
||||||
|
short code;
|
||||||
|
const char *name;
|
||||||
|
} kMetroNames[] = {
|
||||||
|
{500, "Portland-Auburn ME"},
|
||||||
|
{501, "New York NY"},
|
||||||
|
{502, "Binghamton NY"},
|
||||||
|
{503, "Macon GA"},
|
||||||
|
{504, "Philadelphia PA"},
|
||||||
|
{505, "Detroit MI"},
|
||||||
|
{506, "Boston MA-Manchester NH"},
|
||||||
|
{507, "Savannah GA"},
|
||||||
|
{508, "Pittsburgh PA"},
|
||||||
|
{509, "Ft. Wayne IN"},
|
||||||
|
{510, "Cleveland-Akron (Canton) OH"},
|
||||||
|
{511, "Washington DC (Hagerstown MD)"},
|
||||||
|
{512, "Baltimore MD"},
|
||||||
|
{513, "Flint-Saginaw-Bay City MI"},
|
||||||
|
{514, "Buffalo NY"},
|
||||||
|
{515, "Cincinnati OH"},
|
||||||
|
{516, "Erie PA"},
|
||||||
|
{517, "Charlotte NC"},
|
||||||
|
{518, "Greensboro-High Point-Winston Salem NC"},
|
||||||
|
{519, "Charleston SC"},
|
||||||
|
{520, "Augusta GA"},
|
||||||
|
{521, "Providence RI-New Bedford MA"},
|
||||||
|
{522, "Columbus GA"},
|
||||||
|
{523, "Burlington VT-Plattsburgh NY"},
|
||||||
|
{524, "Atlanta GA"},
|
||||||
|
{525, "Albany GA"},
|
||||||
|
{526, "Utica NY"},
|
||||||
|
{527, "Indianapolis IN"},
|
||||||
|
{528, "Miami-Ft. Lauderdale FL"},
|
||||||
|
{529, "Louisville KY"},
|
||||||
|
{530, "Tallahassee FL-Thomasville GA"},
|
||||||
|
{531, "Tri-Cities TN-VA"},
|
||||||
|
{532, "Albany-Schenectady-Troy NY"},
|
||||||
|
{533, "Hartford & New Haven CT"},
|
||||||
|
{534, "Orlando-Daytona Beach-Melbourne FL"},
|
||||||
|
{535, "Columbus OH"},
|
||||||
|
{536, "Youngstown OH"},
|
||||||
|
{537, "Bangor ME"},
|
||||||
|
{538, "Rochester NY"},
|
||||||
|
{539, "Tampa-St. Petersburg (Sarasota) FL"},
|
||||||
|
{540, "Traverse City-Cadillac MI"},
|
||||||
|
{541, "Lexington KY"},
|
||||||
|
{542, "Dayton OH"},
|
||||||
|
{543, "Springfield-Holyoke MA"},
|
||||||
|
{544, "Norfolk-Portsmouth-Newport News VA"},
|
||||||
|
{545, "Greenville-New Bern-Washington NC"},
|
||||||
|
{546, "Columbia SC"},
|
||||||
|
{547, "Toledo OH"},
|
||||||
|
{548, "West Palm Beach-Ft. Pierce FL"},
|
||||||
|
{549, "Watertown NY"},
|
||||||
|
{550, "Wilmington NC"},
|
||||||
|
{551, "Lansing MI"},
|
||||||
|
{552, "Presque Isle ME"},
|
||||||
|
{553, "Marquette MI"},
|
||||||
|
{554, "Wheeling WV-Steubenville OH"},
|
||||||
|
{555, "Syracuse NY"},
|
||||||
|
{556, "Richmond-Petersburg VA"},
|
||||||
|
{557, "Knoxville TN"},
|
||||||
|
{558, "Lima OH"},
|
||||||
|
{559, "Bluefield-Beckley-Oak Hill WV"},
|
||||||
|
{560, "Raleigh-Durham (Fayetteville) NC"},
|
||||||
|
{561, "Jacksonville FL"},
|
||||||
|
{563, "Grand Rapids-Kalamazoo-Battle Creek MI"},
|
||||||
|
{564, "Charleston-Huntington WV"},
|
||||||
|
{565, "Elmira NY"},
|
||||||
|
{566, "Harrisburg-Lancaster-Lebanon-York PA"},
|
||||||
|
{567, "Greenville-Spartanburg SC-Asheville NC-Anderson SC"},
|
||||||
|
{569, "Harrisonburg VA"},
|
||||||
|
{570, "Florence-Myrtle Beach SC"},
|
||||||
|
{571, "Ft. Myers-Naples FL"},
|
||||||
|
{573, "Roanoke-Lynchburg VA"},
|
||||||
|
{574, "Johnstown-Altoona PA"},
|
||||||
|
{575, "Chattanooga TN"},
|
||||||
|
{576, "Salisbury MD"},
|
||||||
|
{577, "Wilkes Barre-Scranton PA"},
|
||||||
|
{581, "Terre Haute IN"},
|
||||||
|
{582, "Lafayette IN"},
|
||||||
|
{583, "Alpena MI"},
|
||||||
|
{584, "Charlottesville VA"},
|
||||||
|
{588, "South Bend-Elkhart IN"},
|
||||||
|
{592, "Gainesville FL"},
|
||||||
|
{596, "Zanesville OH"},
|
||||||
|
{597, "Parkersburg WV"},
|
||||||
|
{598, "Clarksburg-Weston WV"},
|
||||||
|
{600, "Corpus Christi TX"},
|
||||||
|
{602, "Chicago IL"},
|
||||||
|
{603, "Joplin MO-Pittsburg KS"},
|
||||||
|
{604, "Columbia-Jefferson City MO"},
|
||||||
|
{605, "Topeka KS"},
|
||||||
|
{606, "Dothan AL"},
|
||||||
|
{609, "St. Louis MO"},
|
||||||
|
{610, "Rockford IL"},
|
||||||
|
{611, "Rochester MN-Mason City IA-Austin MN"},
|
||||||
|
{612, "Shreveport LA"},
|
||||||
|
{613, "Minneapolis-St. Paul MN"},
|
||||||
|
{616, "Kansas City MO"},
|
||||||
|
{617, "Milwaukee WI"},
|
||||||
|
{618, "Houston TX"},
|
||||||
|
{619, "Springfield MO"},
|
||||||
|
{622, "New Orleans LA"},
|
||||||
|
{623, "Dallas-Ft. Worth TX"},
|
||||||
|
{624, "Sioux City IA"},
|
||||||
|
{625, "Waco-Temple-Bryan TX"},
|
||||||
|
{626, "Victoria TX"},
|
||||||
|
{627, "Wichita Falls TX & Lawton OK"},
|
||||||
|
{628, "Monroe LA-El Dorado AR"},
|
||||||
|
{630, "Birmingham AL"},
|
||||||
|
{631, "Ottumwa IA-Kirksville MO"},
|
||||||
|
{632, "Paducah KY-Cape Girardeau MO-Harrisburg-Mount Vernon IL"},
|
||||||
|
{633, "Odessa-Midland TX"},
|
||||||
|
{634, "Amarillo TX"},
|
||||||
|
{635, "Austin TX"},
|
||||||
|
{636, "Harlingen-Weslaco-Brownsville-McAllen TX"},
|
||||||
|
{637, "Cedar Rapids-Waterloo-Iowa City & Dubuque IA"},
|
||||||
|
{638, "St. Joseph MO"},
|
||||||
|
{639, "Jackson TN"},
|
||||||
|
{640, "Memphis TN"},
|
||||||
|
{641, "San Antonio TX"},
|
||||||
|
{642, "Lafayette LA"},
|
||||||
|
{643, "Lake Charles LA"},
|
||||||
|
{644, "Alexandria LA"},
|
||||||
|
{647, "Greenwood-Greenville MS"},
|
||||||
|
{648, "Champaign & Springfield-Decatur,IL"},
|
||||||
|
{649, "Evansville IN"},
|
||||||
|
{650, "Oklahoma City OK"},
|
||||||
|
{651, "Lubbock TX"},
|
||||||
|
{652, "Omaha NE"},
|
||||||
|
{656, "Panama City FL"},
|
||||||
|
{657, "Sherman TX-Ada OK"},
|
||||||
|
{658, "Green Bay-Appleton WI"},
|
||||||
|
{659, "Nashville TN"},
|
||||||
|
{661, "San Angelo TX"},
|
||||||
|
{662, "Abilene-Sweetwater TX"},
|
||||||
|
{669, "Madison WI"},
|
||||||
|
{670, "Ft. Smith-Fayetteville-Springdale-Rogers AR"},
|
||||||
|
{671, "Tulsa OK"},
|
||||||
|
{673, "Columbus-Tupelo-West Point MS"},
|
||||||
|
{675, "Peoria-Bloomington IL"},
|
||||||
|
{676, "Duluth MN-Superior WI"},
|
||||||
|
{678, "Wichita-Hutchinson KS"},
|
||||||
|
{679, "Des Moines-Ames IA"},
|
||||||
|
{682, "Davenport IA-Rock Island-Moline IL"},
|
||||||
|
{686, "Mobile AL-Pensacola (Ft. Walton Beach) FL"},
|
||||||
|
{687, "Minot-Bismarck-Dickinson(Williston) ND"},
|
||||||
|
{691, "Huntsville-Decatur (Florence) AL"},
|
||||||
|
{692, "Beaumont-Port Arthur TX"},
|
||||||
|
{693, "Little Rock-Pine Bluff AR"},
|
||||||
|
{698, "Montgomery (Selma) AL"},
|
||||||
|
{702, "La Crosse-Eau Claire WI"},
|
||||||
|
{705, "Wausau-Rhinelander WI"},
|
||||||
|
{709, "Tyler-Longview(Lufkin & Nacogdoches) TX"},
|
||||||
|
{710, "Hattiesburg-Laurel MS"},
|
||||||
|
{711, "Meridian MS"},
|
||||||
|
{716, "Baton Rouge LA"},
|
||||||
|
{717, "Quincy IL-Hannibal MO-Keokuk IA"},
|
||||||
|
{718, "Jackson MS"},
|
||||||
|
{722, "Lincoln & Hastings-Kearney NE"},
|
||||||
|
{724, "Fargo-Valley City ND"},
|
||||||
|
{725, "Sioux Falls(Mitchell) SD"},
|
||||||
|
{734, "Jonesboro AR"},
|
||||||
|
{736, "Bowling Green KY"},
|
||||||
|
{737, "Mankato MN"},
|
||||||
|
{740, "North Platte NE"},
|
||||||
|
{743, "Anchorage AK"},
|
||||||
|
{744, "Honolulu HI"},
|
||||||
|
{745, "Fairbanks AK"},
|
||||||
|
{746, "Biloxi-Gulfport MS"},
|
||||||
|
{747, "Juneau AK"},
|
||||||
|
{749, "Laredo TX"},
|
||||||
|
{751, "Denver CO"},
|
||||||
|
{752, "Colorado Springs-Pueblo CO"},
|
||||||
|
{753, "Phoenix AZ"},
|
||||||
|
{754, "Butte-Bozeman MT"},
|
||||||
|
{755, "Great Falls MT"},
|
||||||
|
{756, "Billings MT"},
|
||||||
|
{757, "Boise ID"},
|
||||||
|
{758, "Idaho Falls-Pocatello ID"},
|
||||||
|
{759, "Cheyenne WY-Scottsbluff NE"},
|
||||||
|
{760, "Twin Falls ID"},
|
||||||
|
{762, "Missoula MT"},
|
||||||
|
{764, "Rapid City SD"},
|
||||||
|
{765, "El Paso TX"},
|
||||||
|
{766, "Helena MT"},
|
||||||
|
{767, "Casper-Riverton WY"},
|
||||||
|
{770, "Salt Lake City UT"},
|
||||||
|
{771, "Yuma AZ-El Centro CA"},
|
||||||
|
{773, "Grand Junction-Montrose CO"},
|
||||||
|
{789, "Tucson (Sierra Vista) AZ"},
|
||||||
|
{790, "Albuquerque-Santa Fe NM"},
|
||||||
|
{798, "Glendive MT"},
|
||||||
|
{800, "Bakersfield CA"},
|
||||||
|
{801, "Eugene OR"},
|
||||||
|
{802, "Eureka CA"},
|
||||||
|
{803, "Los Angeles CA"},
|
||||||
|
{804, "Palm Springs CA"},
|
||||||
|
{807, "San Francisco-Oakland-San Jose CA"},
|
||||||
|
{810, "Yakima-Pasco-Richland-Kennewick WA"},
|
||||||
|
{811, "Reno NV"},
|
||||||
|
{813, "Medford-Klamath Falls OR"},
|
||||||
|
{819, "Seattle-Tacoma WA"},
|
||||||
|
{820, "Portland OR"},
|
||||||
|
{821, "Bend OR"},
|
||||||
|
{825, "San Diego CA"},
|
||||||
|
{828, "Monterey-Salinas CA"},
|
||||||
|
{839, "Las Vegas NV"},
|
||||||
|
{855, "Santa Barbara-Santa Maria-San Luis Obispo CA"},
|
||||||
|
{862, "Sacramento-Stockton-Modesto CA"},
|
||||||
|
{866, "Fresno-Visalia CA"},
|
||||||
|
{868, "Chico-Redding CA"},
|
||||||
|
{881, "Spokane WA"},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns U.S. Metropolitan Area name.
|
||||||
|
* @see Google Adwords c. 2010
|
||||||
|
*/
|
||||||
|
const char *GetMetroName(int code) {
|
||||||
|
int m, l, r;
|
||||||
|
l = 0;
|
||||||
|
r = ARRAYLEN(kMetroNames) - 1;
|
||||||
|
while (l <= r) {
|
||||||
|
m = (l + r) >> 1;
|
||||||
|
if (kMetroNames[m].code < code) {
|
||||||
|
l = m + 1;
|
||||||
|
} else if (kMetroNames[m].code > code) {
|
||||||
|
r = m - 1;
|
||||||
|
} else {
|
||||||
|
return kMetroNames[m].name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
58
third_party/maxmind/maxmind.mk
vendored
Normal file
58
third_party/maxmind/maxmind.mk
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
|
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||||
|
|
||||||
|
PKGS += THIRD_PARTY_MAXMIND
|
||||||
|
|
||||||
|
THIRD_PARTY_MAXMIND_ARTIFACTS += THIRD_PARTY_MAXMIND_A
|
||||||
|
THIRD_PARTY_MAXMIND = $(THIRD_PARTY_MAXMIND_A_DEPS) $(THIRD_PARTY_MAXMIND_A)
|
||||||
|
THIRD_PARTY_MAXMIND_A = o/$(MODE)/third_party/maxmind/maxmind.a
|
||||||
|
THIRD_PARTY_MAXMIND_A_FILES := $(wildcard third_party/maxmind/*)
|
||||||
|
THIRD_PARTY_MAXMIND_A_HDRS = $(filter %.h,$(THIRD_PARTY_MAXMIND_A_FILES))
|
||||||
|
THIRD_PARTY_MAXMIND_A_SRCS = $(filter %.c,$(THIRD_PARTY_MAXMIND_A_FILES))
|
||||||
|
|
||||||
|
THIRD_PARTY_MAXMIND_A_OBJS = \
|
||||||
|
$(THIRD_PARTY_MAXMIND_A_SRCS:%.c=o/$(MODE)/%.o)
|
||||||
|
|
||||||
|
THIRD_PARTY_MAXMIND_A_CHECKS = \
|
||||||
|
$(THIRD_PARTY_MAXMIND_A).pkg \
|
||||||
|
$(THIRD_PARTY_MAXMIND_A_HDRS:%=o/$(MODE)/%.ok)
|
||||||
|
|
||||||
|
THIRD_PARTY_MAXMIND_A_DIRECTDEPS = \
|
||||||
|
LIBC_CALLS \
|
||||||
|
LIBC_FMT \
|
||||||
|
LIBC_INTRIN \
|
||||||
|
LIBC_MEM \
|
||||||
|
LIBC_NEXGEN32E \
|
||||||
|
LIBC_RUNTIME \
|
||||||
|
LIBC_STDIO \
|
||||||
|
LIBC_STR \
|
||||||
|
LIBC_STUBS \
|
||||||
|
LIBC_SYSV \
|
||||||
|
LIBC_UNICODE
|
||||||
|
|
||||||
|
THIRD_PARTY_MAXMIND_A_DEPS := \
|
||||||
|
$(call uniq,$(foreach x,$(THIRD_PARTY_MAXMIND_A_DIRECTDEPS),$($(x))))
|
||||||
|
|
||||||
|
$(THIRD_PARTY_MAXMIND_A): \
|
||||||
|
third_party/maxmind/ \
|
||||||
|
$(THIRD_PARTY_MAXMIND_A).pkg \
|
||||||
|
$(THIRD_PARTY_MAXMIND_A_OBJS)
|
||||||
|
|
||||||
|
$(THIRD_PARTY_MAXMIND_A).pkg: \
|
||||||
|
$(THIRD_PARTY_MAXMIND_A_OBJS) \
|
||||||
|
$(foreach x,$(THIRD_PARTY_MAXMIND_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||||
|
|
||||||
|
$(THIRD_PARTY_MAXMIND_A_OBJS): \
|
||||||
|
OVERRIDE_CFLAGS += \
|
||||||
|
-fdata-sections \
|
||||||
|
-ffunction-sections
|
||||||
|
|
||||||
|
THIRD_PARTY_MAXMIND_LIBS = $(foreach x,$(THIRD_PARTY_MAXMIND_ARTIFACTS),$($(x)))
|
||||||
|
THIRD_PARTY_MAXMIND_SRCS = $(foreach x,$(THIRD_PARTY_MAXMIND_ARTIFACTS),$($(x)_SRCS))
|
||||||
|
THIRD_PARTY_MAXMIND_HDRS = $(foreach x,$(THIRD_PARTY_MAXMIND_ARTIFACTS),$($(x)_HDRS))
|
||||||
|
THIRD_PARTY_MAXMIND_CHECKS = $(foreach x,$(THIRD_PARTY_MAXMIND_ARTIFACTS),$($(x)_CHECKS))
|
||||||
|
THIRD_PARTY_MAXMIND_OBJS = $(foreach x,$(THIRD_PARTY_MAXMIND_ARTIFACTS),$($(x)_OBJS))
|
||||||
|
|
||||||
|
.PHONY: o/$(MODE)/third_party/maxmind
|
||||||
|
o/$(MODE)/third_party/maxmind: \
|
||||||
|
$(THIRD_PARTY_MAXMIND_CHECKS)
|
1617
third_party/maxmind/maxminddb.c
vendored
Normal file
1617
third_party/maxmind/maxminddb.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
182
third_party/maxmind/maxminddb.h
vendored
Normal file
182
third_party/maxmind/maxminddb.h
vendored
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
#ifndef COSMOPOLITAN_THIRD_PARTY_MAXMIND_MAXMINDDB_H_
|
||||||
|
#define COSMOPOLITAN_THIRD_PARTY_MAXMIND_MAXMINDDB_H_
|
||||||
|
#include "libc/sock/sock.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
|
||||||
|
#define MMDB_MODE_MMAP 1
|
||||||
|
#define MMDB_MODE_MASK 7
|
||||||
|
|
||||||
|
#define MMDB_DATA_TYPE_EXTENDED 0
|
||||||
|
#define MMDB_DATA_TYPE_POINTER 1
|
||||||
|
#define MMDB_DATA_TYPE_UTF8_STRING 2
|
||||||
|
#define MMDB_DATA_TYPE_DOUBLE 3
|
||||||
|
#define MMDB_DATA_TYPE_BYTES 4
|
||||||
|
#define MMDB_DATA_TYPE_UINT16 5
|
||||||
|
#define MMDB_DATA_TYPE_UINT32 6
|
||||||
|
#define MMDB_DATA_TYPE_MAP 7
|
||||||
|
#define MMDB_DATA_TYPE_INT32 8
|
||||||
|
#define MMDB_DATA_TYPE_UINT64 9
|
||||||
|
#define MMDB_DATA_TYPE_UINT128 10
|
||||||
|
#define MMDB_DATA_TYPE_ARRAY 11
|
||||||
|
#define MMDB_DATA_TYPE_CONTAINER 12
|
||||||
|
#define MMDB_DATA_TYPE_END_MARKER 13
|
||||||
|
#define MMDB_DATA_TYPE_BOOLEAN 14
|
||||||
|
#define MMDB_DATA_TYPE_FLOAT 15
|
||||||
|
|
||||||
|
#define MMDB_RECORD_TYPE_SEARCH_NODE 0
|
||||||
|
#define MMDB_RECORD_TYPE_EMPTY 1
|
||||||
|
#define MMDB_RECORD_TYPE_DATA 2
|
||||||
|
#define MMDB_RECORD_TYPE_INVALID 3
|
||||||
|
|
||||||
|
#define MMDB_SUCCESS 0
|
||||||
|
#define MMDB_FILE_OPEN_ERROR 1
|
||||||
|
#define MMDB_CORRUPT_SEARCH_TREE_ERROR 2
|
||||||
|
#define MMDB_INVALID_METADATA_ERROR 3
|
||||||
|
#define MMDB_IO_ERROR 4
|
||||||
|
#define MMDB_OUT_OF_MEMORY_ERROR 5
|
||||||
|
#define MMDB_UNKNOWN_DATABASE_FORMAT_ERROR 6
|
||||||
|
#define MMDB_INVALID_DATA_ERROR 7
|
||||||
|
#define MMDB_INVALID_LOOKUP_PATH_ERROR 8
|
||||||
|
#define MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR 9
|
||||||
|
#define MMDB_INVALID_NODE_NUMBER_ERROR 10
|
||||||
|
#define MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR 11
|
||||||
|
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
/* This is a pointer into the data section for a given IP address lookup */
|
||||||
|
typedef struct MMDB_entry_s {
|
||||||
|
const struct MMDB_s *mmdb;
|
||||||
|
uint32_t offset;
|
||||||
|
} MMDB_entry_s;
|
||||||
|
|
||||||
|
typedef struct MMDB_lookup_result_s {
|
||||||
|
bool found_entry;
|
||||||
|
MMDB_entry_s entry;
|
||||||
|
uint16_t netmask;
|
||||||
|
} MMDB_lookup_result_s;
|
||||||
|
|
||||||
|
typedef struct MMDB_entry_data_s {
|
||||||
|
bool has_data;
|
||||||
|
union {
|
||||||
|
uint32_t pointer;
|
||||||
|
const char *utf8_string;
|
||||||
|
double double_value;
|
||||||
|
const uint8_t *bytes;
|
||||||
|
uint16_t uint16;
|
||||||
|
uint32_t uint32;
|
||||||
|
int32_t int32;
|
||||||
|
uint64_t uint64;
|
||||||
|
uint128_t uint128;
|
||||||
|
bool boolean;
|
||||||
|
float float_value;
|
||||||
|
};
|
||||||
|
/* This is a 0 if a given entry cannot be found. This can only happen
|
||||||
|
* when a call to MMDB_(v)get_value() asks for hash keys or array
|
||||||
|
* indices that don't exist. */
|
||||||
|
uint32_t offset;
|
||||||
|
/* This is the next entry in the data section, but it's really only
|
||||||
|
* relevant for entries that part of a larger map or array
|
||||||
|
* struct. There's no good reason for an end user to look at this
|
||||||
|
* directly. */
|
||||||
|
uint32_t offset_to_next;
|
||||||
|
/* This is only valid for strings, utf8_strings or binary data */
|
||||||
|
uint32_t data_size;
|
||||||
|
/* This is an MMDB_DATA_TYPE_* constant */
|
||||||
|
uint32_t type;
|
||||||
|
} MMDB_entry_data_s;
|
||||||
|
|
||||||
|
/* This is the return type when someone asks for all the entry data in a map or
|
||||||
|
* array */
|
||||||
|
typedef struct MMDB_entry_data_list_s {
|
||||||
|
MMDB_entry_data_s entry_data;
|
||||||
|
struct MMDB_entry_data_list_s *next;
|
||||||
|
void *pool;
|
||||||
|
} MMDB_entry_data_list_s;
|
||||||
|
|
||||||
|
typedef struct MMDB_description_s {
|
||||||
|
const char *language;
|
||||||
|
const char *description;
|
||||||
|
} MMDB_description_s;
|
||||||
|
|
||||||
|
/* WARNING: do not add new fields to this struct without bumping the SONAME.
|
||||||
|
* The struct is allocated by the users of this library and increasing the
|
||||||
|
* size will cause existing users to allocate too little space when the shared
|
||||||
|
* library is upgraded */
|
||||||
|
typedef struct MMDB_metadata_s {
|
||||||
|
uint32_t node_count;
|
||||||
|
uint16_t record_size;
|
||||||
|
uint16_t ip_version;
|
||||||
|
const char *database_type;
|
||||||
|
struct {
|
||||||
|
size_t count;
|
||||||
|
const char **names;
|
||||||
|
} languages;
|
||||||
|
uint16_t binary_format_major_version;
|
||||||
|
uint16_t binary_format_minor_version;
|
||||||
|
uint64_t build_epoch;
|
||||||
|
struct {
|
||||||
|
size_t count;
|
||||||
|
MMDB_description_s **descriptions;
|
||||||
|
} description;
|
||||||
|
/* See above warning before adding fields */
|
||||||
|
} MMDB_metadata_s;
|
||||||
|
|
||||||
|
/* WARNING: do not add new fields to this struct without bumping the SONAME.
|
||||||
|
* The struct is allocated by the users of this library and increasing the
|
||||||
|
* size will cause existing users to allocate too little space when the shared
|
||||||
|
* library is upgraded */
|
||||||
|
typedef struct MMDB_ipv4_start_node_s {
|
||||||
|
uint16_t netmask;
|
||||||
|
uint32_t node_value;
|
||||||
|
/* See above warning before adding fields */
|
||||||
|
} MMDB_ipv4_start_node_s;
|
||||||
|
|
||||||
|
/* WARNING: do not add new fields to this struct without bumping the SONAME.
|
||||||
|
* The struct is allocated by the users of this library and increasing the
|
||||||
|
* size will cause existing users to allocate too little space when the shared
|
||||||
|
* library is upgraded */
|
||||||
|
typedef struct MMDB_s {
|
||||||
|
uint32_t flags;
|
||||||
|
const char *filename;
|
||||||
|
ssize_t file_size;
|
||||||
|
const uint8_t *file_content;
|
||||||
|
const uint8_t *data_section;
|
||||||
|
uint32_t data_section_size;
|
||||||
|
const uint8_t *metadata_section;
|
||||||
|
uint32_t metadata_section_size;
|
||||||
|
uint16_t full_record_byte_size;
|
||||||
|
uint16_t depth;
|
||||||
|
MMDB_ipv4_start_node_s ipv4_start_node;
|
||||||
|
MMDB_metadata_s metadata;
|
||||||
|
/* See above warning before adding fields */
|
||||||
|
} MMDB_s;
|
||||||
|
|
||||||
|
typedef struct MMDB_search_node_s {
|
||||||
|
uint64_t left_record;
|
||||||
|
uint64_t right_record;
|
||||||
|
uint8_t left_record_type;
|
||||||
|
uint8_t right_record_type;
|
||||||
|
MMDB_entry_s left_record_entry;
|
||||||
|
MMDB_entry_s right_record_entry;
|
||||||
|
} MMDB_search_node_s;
|
||||||
|
|
||||||
|
void MMDB_close(MMDB_s *);
|
||||||
|
int MMDB_open(const char *, uint32_t, MMDB_s *);
|
||||||
|
MMDB_lookup_result_s MMDB_lookup(const MMDB_s *, uint32_t, int *);
|
||||||
|
int MMDB_read_node(const MMDB_s *, uint32_t, MMDB_search_node_s *);
|
||||||
|
int MMDB_get_value(MMDB_entry_s *, MMDB_entry_data_s *, ...);
|
||||||
|
int MMDB_vget_value(MMDB_entry_s *, MMDB_entry_data_s *, va_list);
|
||||||
|
int MMDB_aget_value(MMDB_entry_s *, MMDB_entry_data_s *, const char *const *);
|
||||||
|
int MMDB_get_metadata_as_entry_data_list(const MMDB_s *,
|
||||||
|
MMDB_entry_data_list_s **);
|
||||||
|
int MMDB_get_entry_data_list(MMDB_entry_s *, MMDB_entry_data_list_s **);
|
||||||
|
void MMDB_free_entry_data_list(MMDB_entry_data_list_s *);
|
||||||
|
int MMDB_dump_entry_data_list(FILE *, MMDB_entry_data_list_s *, int);
|
||||||
|
const char *MMDB_lib_version(void);
|
||||||
|
const char *MMDB_strerror(int);
|
||||||
|
const char *GetMetroName(int);
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_THIRD_PARTY_MAXMIND_MAXMINDDB_H_ */
|
3
third_party/third_party.mk
vendored
3
third_party/third_party.mk
vendored
|
@ -14,8 +14,9 @@ o/$(MODE)/third_party: \
|
||||||
o/$(MODE)/third_party/linenoise \
|
o/$(MODE)/third_party/linenoise \
|
||||||
o/$(MODE)/third_party/lua \
|
o/$(MODE)/third_party/lua \
|
||||||
o/$(MODE)/third_party/lz4cli \
|
o/$(MODE)/third_party/lz4cli \
|
||||||
o/$(MODE)/third_party/mbedtls \
|
|
||||||
o/$(MODE)/third_party/make \
|
o/$(MODE)/third_party/make \
|
||||||
|
o/$(MODE)/third_party/maxmind \
|
||||||
|
o/$(MODE)/third_party/mbedtls \
|
||||||
o/$(MODE)/third_party/musl \
|
o/$(MODE)/third_party/musl \
|
||||||
o/$(MODE)/third_party/python \
|
o/$(MODE)/third_party/python \
|
||||||
o/$(MODE)/third_party/quickjs \
|
o/$(MODE)/third_party/quickjs \
|
||||||
|
|
|
@ -1146,6 +1146,26 @@ RE MODULE
|
||||||
end of the line. This flag may only be used with re.search and
|
end of the line. This flag may only be used with re.search and
|
||||||
regex_t*:search.
|
regex_t*:search.
|
||||||
|
|
||||||
|
MAXMIND MODULE
|
||||||
|
|
||||||
|
This module may be used to get city/country/asn/etc from IPs, e.g.
|
||||||
|
|
||||||
|
-- .init.lua
|
||||||
|
maxmind = require "maxmind"
|
||||||
|
asndb = maxmind.open('/usr/local/share/maxmind/GeoLite2-ASN.mmdb')
|
||||||
|
|
||||||
|
-- request handler
|
||||||
|
as = asndb:lookup(GetRemoteAddr())
|
||||||
|
if as then
|
||||||
|
asnum = as:get("autonomous_system_number")
|
||||||
|
asorg = as:get("autonomous_system_organization")
|
||||||
|
Write(EscapeHtml(asnum))
|
||||||
|
Write(' ')
|
||||||
|
Write(EscapeHtml(asorg))
|
||||||
|
end
|
||||||
|
|
||||||
|
For further details, please see tool/net/lmaxmind.c
|
||||||
|
|
||||||
CONSTANTS
|
CONSTANTS
|
||||||
|
|
||||||
kLogDebug
|
kLogDebug
|
||||||
|
|
301
tool/net/lmaxmind.c
Normal file
301
tool/net/lmaxmind.c
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/lua/lauxlib.h"
|
||||||
|
#include "third_party/lua/lua.h"
|
||||||
|
#include "third_party/lua/luaconf.h"
|
||||||
|
#include "third_party/maxmind/maxminddb.h"
|
||||||
|
|
||||||
|
struct MaxmindDb {
|
||||||
|
int refs;
|
||||||
|
MMDB_s mmdb;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MaxmindResult {
|
||||||
|
uint32_t ip;
|
||||||
|
struct MaxmindDb *db;
|
||||||
|
MMDB_lookup_result_s mmlr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *GetMmdbError(int err) {
|
||||||
|
switch (err) {
|
||||||
|
case MMDB_FILE_OPEN_ERROR:
|
||||||
|
return "FILE_OPEN_ERROR";
|
||||||
|
case MMDB_CORRUPT_SEARCH_TREE_ERROR:
|
||||||
|
return "CORRUPT_SEARCH_TREE_ERROR";
|
||||||
|
case MMDB_INVALID_METADATA_ERROR:
|
||||||
|
return "INVALID_METADATA_ERROR";
|
||||||
|
case MMDB_IO_ERROR:
|
||||||
|
return "IO_ERROR";
|
||||||
|
case MMDB_OUT_OF_MEMORY_ERROR:
|
||||||
|
return "OUT_OF_MEMORY_ERROR";
|
||||||
|
case MMDB_UNKNOWN_DATABASE_FORMAT_ERROR:
|
||||||
|
return "UNKNOWN_DATABASE_FORMAT_ERROR";
|
||||||
|
case MMDB_INVALID_DATA_ERROR:
|
||||||
|
return "INVALID_DATA_ERROR";
|
||||||
|
case MMDB_INVALID_LOOKUP_PATH_ERROR:
|
||||||
|
return "INVALID_LOOKUP_PATH_ERROR";
|
||||||
|
case MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR:
|
||||||
|
return "LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR";
|
||||||
|
case MMDB_INVALID_NODE_NUMBER_ERROR:
|
||||||
|
return "INVALID_NODE_NUMBER_ERROR";
|
||||||
|
case MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR:
|
||||||
|
return "IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int LuaMaxmindOpen(lua_State *L) {
|
||||||
|
int err;
|
||||||
|
const char *p;
|
||||||
|
struct MaxmindDb **udb, *db;
|
||||||
|
p = luaL_checklstring(L, 1, 0);
|
||||||
|
db = xmalloc(sizeof(struct MaxmindDb));
|
||||||
|
if ((err = MMDB_open(p, 0, &db->mmdb)) != MMDB_SUCCESS) {
|
||||||
|
free(db);
|
||||||
|
luaL_error(L, "MMDB_open(%s) → MMDB_%s", p, GetMmdbError(err));
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
db->refs = 1;
|
||||||
|
udb = lua_newuserdatauv(L, sizeof(db), 1);
|
||||||
|
luaL_setmetatable(L, "MaxmindDb*");
|
||||||
|
*udb = db;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static wontreturn void LuaThrowMaxmindIpError(lua_State *L,
|
||||||
|
const char *function_name,
|
||||||
|
uint32_t ip, int err) {
|
||||||
|
luaL_error(L, "%s(%d.%d.%d.%d) → MMDB_%s", function_name,
|
||||||
|
(ip & 0xff000000) >> 030, (ip & 0x00ff0000) >> 020,
|
||||||
|
(ip & 0x0000ff00) >> 010, (ip & 0x000000ff) >> 000,
|
||||||
|
GetMmdbError(err));
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LuaMaxmindDbLookup(lua_State *L) {
|
||||||
|
int err;
|
||||||
|
lua_Integer ip;
|
||||||
|
struct MaxmindDb **udb, *db;
|
||||||
|
struct MaxmindResult **ur, *r;
|
||||||
|
udb = luaL_checkudata(L, 1, "MaxmindDb*");
|
||||||
|
ip = luaL_checkinteger(L, 2);
|
||||||
|
if (ip < 0 || ip > 0xffffffff) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
db = *udb;
|
||||||
|
r = xmalloc(sizeof(struct MaxmindResult));
|
||||||
|
r->mmlr = MMDB_lookup(&db->mmdb, ip, &err);
|
||||||
|
if (err) {
|
||||||
|
free(r);
|
||||||
|
LuaThrowMaxmindIpError(L, "MMDB_lookup", ip, err);
|
||||||
|
}
|
||||||
|
if (!r->mmlr.found_entry) {
|
||||||
|
free(r);
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
r->ip = ip;
|
||||||
|
r->db = db;
|
||||||
|
r->db->refs++;
|
||||||
|
ur = lua_newuserdatauv(L, sizeof(r), 1);
|
||||||
|
luaL_setmetatable(L, "MaxmindResult*");
|
||||||
|
*ur = r;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LuaMaxmindResultNetmask(lua_State *L) {
|
||||||
|
struct MaxmindResult **ur;
|
||||||
|
ur = luaL_checkudata(L, 1, "MaxmindResult*");
|
||||||
|
lua_pushinteger(L, (*ur)->mmlr.netmask - (128 - 32));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MMDB_entry_data_list_s *LuaMaxmindDump(lua_State *L,
|
||||||
|
MMDB_entry_data_list_s *dl) {
|
||||||
|
size_t i, n;
|
||||||
|
char ibuf[64];
|
||||||
|
switch (dl->entry_data.type) {
|
||||||
|
case MMDB_DATA_TYPE_UTF8_STRING:
|
||||||
|
lua_pushlstring(L, dl->entry_data.utf8_string, dl->entry_data.data_size);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_BYTES:
|
||||||
|
lua_pushlstring(L, (void *)dl->entry_data.bytes,
|
||||||
|
dl->entry_data.data_size);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_INT32:
|
||||||
|
lua_pushinteger(L, dl->entry_data.int32);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_UINT16:
|
||||||
|
lua_pushinteger(L, dl->entry_data.uint16);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_UINT32:
|
||||||
|
lua_pushinteger(L, dl->entry_data.uint32);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_BOOLEAN:
|
||||||
|
lua_pushboolean(L, dl->entry_data.boolean);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_UINT64:
|
||||||
|
lua_pushinteger(L, dl->entry_data.uint64);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_UINT128:
|
||||||
|
sprintf(ibuf, "%#jx", dl->entry_data.uint128);
|
||||||
|
lua_pushstring(L, ibuf);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_DOUBLE:
|
||||||
|
lua_pushnumber(L, dl->entry_data.double_value);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_FLOAT:
|
||||||
|
lua_pushnumber(L, dl->entry_data.float_value);
|
||||||
|
return dl->next;
|
||||||
|
case MMDB_DATA_TYPE_ARRAY:
|
||||||
|
lua_newtable(L);
|
||||||
|
n = dl->entry_data.data_size;
|
||||||
|
for (dl = dl->next, i = 0; dl && i < n; ++i) {
|
||||||
|
dl = LuaMaxmindDump(L, dl);
|
||||||
|
lua_seti(L, -2, i + 1);
|
||||||
|
}
|
||||||
|
return dl;
|
||||||
|
case MMDB_DATA_TYPE_MAP:
|
||||||
|
lua_newtable(L);
|
||||||
|
n = dl->entry_data.data_size;
|
||||||
|
for (dl = dl->next; dl && n; n--) {
|
||||||
|
dl = LuaMaxmindDump(L, dl);
|
||||||
|
dl = LuaMaxmindDump(L, dl);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
}
|
||||||
|
return dl;
|
||||||
|
default:
|
||||||
|
lua_pushnil(L);
|
||||||
|
return dl->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LuaMaxmindResultGet(lua_State *L) {
|
||||||
|
int i, n, err;
|
||||||
|
const char **path;
|
||||||
|
MMDB_entry_s entry, *ep;
|
||||||
|
MMDB_entry_data_s edata;
|
||||||
|
struct MaxmindResult **ur;
|
||||||
|
MMDB_entry_data_list_s *dl;
|
||||||
|
n = lua_gettop(L) - 1;
|
||||||
|
ur = luaL_checkudata(L, 1, "MaxmindResult*");
|
||||||
|
if (n <= 0) {
|
||||||
|
ep = &(*ur)->mmlr.entry;
|
||||||
|
} else {
|
||||||
|
path = xcalloc(n + 1, sizeof(const char *));
|
||||||
|
for (i = 0; i < n; ++i) path[i] = lua_tostring(L, 2 + i);
|
||||||
|
err = MMDB_aget_value(&(*ur)->mmlr.entry, &edata, path);
|
||||||
|
free(path);
|
||||||
|
if (err) LuaThrowMaxmindIpError(L, "getpath", (*ur)->ip, err);
|
||||||
|
if (!edata.offset) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
entry.mmdb = (*ur)->mmlr.entry.mmdb;
|
||||||
|
entry.offset = edata.offset;
|
||||||
|
ep = &entry;
|
||||||
|
}
|
||||||
|
err = MMDB_get_entry_data_list(ep, &dl);
|
||||||
|
if (err) LuaThrowMaxmindIpError(L, "getlist", (*ur)->ip, err);
|
||||||
|
LuaMaxmindDump(L, dl);
|
||||||
|
MMDB_free_entry_data_list(dl);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeMaxmindDb(struct MaxmindDb *db) {
|
||||||
|
if (!--db->refs) {
|
||||||
|
MMDB_close(&db->mmdb);
|
||||||
|
free(db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LuaMaxmindDbGc(lua_State *L) {
|
||||||
|
struct MaxmindDb **udb;
|
||||||
|
udb = luaL_checkudata(L, 1, "MaxmindDb*");
|
||||||
|
if (*udb) {
|
||||||
|
FreeMaxmindDb(*udb);
|
||||||
|
*udb = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LuaMaxmindResultGc(lua_State *L) {
|
||||||
|
struct MaxmindResult **ur;
|
||||||
|
ur = luaL_checkudata(L, 1, "MaxmindResult*");
|
||||||
|
if (*ur) {
|
||||||
|
FreeMaxmindDb((*ur)->db);
|
||||||
|
free(*ur);
|
||||||
|
*ur = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const luaL_Reg kLuaMaxmind[] = {
|
||||||
|
{"open", LuaMaxmindOpen}, //
|
||||||
|
{0}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg kLuaMaxmindDbMeth[] = {
|
||||||
|
{"lookup", LuaMaxmindDbLookup}, //
|
||||||
|
{0}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg kLuaMaxmindDbMeta[] = {
|
||||||
|
{"__gc", LuaMaxmindDbGc}, //
|
||||||
|
{0}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg kLuaMaxmindResultMeth[] = {
|
||||||
|
{"get", LuaMaxmindResultGet}, //
|
||||||
|
{"netmask", LuaMaxmindResultNetmask}, //
|
||||||
|
{0}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg kLuaMaxmindResultMeta[] = {
|
||||||
|
{"__gc", LuaMaxmindResultGc}, //
|
||||||
|
{0}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
static void LuaMaxmindDb(lua_State *L) {
|
||||||
|
luaL_newmetatable(L, "MaxmindDb*");
|
||||||
|
luaL_setfuncs(L, kLuaMaxmindDbMeta, 0);
|
||||||
|
luaL_newlibtable(L, kLuaMaxmindDbMeth);
|
||||||
|
luaL_setfuncs(L, kLuaMaxmindDbMeth, 0);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LuaMaxmindResult(lua_State *L) {
|
||||||
|
luaL_newmetatable(L, "MaxmindResult*");
|
||||||
|
luaL_setfuncs(L, kLuaMaxmindResultMeta, 0);
|
||||||
|
luaL_newlibtable(L, kLuaMaxmindResultMeth);
|
||||||
|
luaL_setfuncs(L, kLuaMaxmindResultMeth, 0);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaMaxmind(lua_State *L) {
|
||||||
|
luaL_newlib(L, kLuaMaxmind);
|
||||||
|
LuaMaxmindResult(L);
|
||||||
|
LuaMaxmindDb(L);
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ TOOL_NET_DIRECTDEPS = \
|
||||||
THIRD_PARTY_LUA \
|
THIRD_PARTY_LUA \
|
||||||
THIRD_PARTY_MBEDTLS \
|
THIRD_PARTY_MBEDTLS \
|
||||||
THIRD_PARTY_REGEX \
|
THIRD_PARTY_REGEX \
|
||||||
|
THIRD_PARTY_MAXMIND \
|
||||||
THIRD_PARTY_SQLITE3 \
|
THIRD_PARTY_SQLITE3 \
|
||||||
THIRD_PARTY_ZLIB \
|
THIRD_PARTY_ZLIB \
|
||||||
THIRD_PARTY_ARGON2 \
|
THIRD_PARTY_ARGON2 \
|
||||||
|
@ -85,6 +86,7 @@ o/$(MODE)/tool/net/%.com.dbg: \
|
||||||
o/$(MODE)/tool/net/redbean.com.dbg: \
|
o/$(MODE)/tool/net/redbean.com.dbg: \
|
||||||
$(TOOL_NET_DEPS) \
|
$(TOOL_NET_DEPS) \
|
||||||
o/$(MODE)/tool/net/redbean.o \
|
o/$(MODE)/tool/net/redbean.o \
|
||||||
|
o/$(MODE)/tool/net/lmaxmind.o \
|
||||||
o/$(MODE)/tool/net/lsqlite3.o \
|
o/$(MODE)/tool/net/lsqlite3.o \
|
||||||
o/$(MODE)/tool/net/largon2.o \
|
o/$(MODE)/tool/net/largon2.o \
|
||||||
o/$(MODE)/tool/net/net.pkg \
|
o/$(MODE)/tool/net/net.pkg \
|
||||||
|
@ -144,6 +146,7 @@ o/$(MODE)/tool/net/demo/virtualbean.html.zip.o: \
|
||||||
o/$(MODE)/tool/net/redbean-demo.com.dbg: \
|
o/$(MODE)/tool/net/redbean-demo.com.dbg: \
|
||||||
$(TOOL_NET_DEPS) \
|
$(TOOL_NET_DEPS) \
|
||||||
o/$(MODE)/tool/net/redbean.o \
|
o/$(MODE)/tool/net/redbean.o \
|
||||||
|
o/$(MODE)/tool/net/lmaxmind.o \
|
||||||
o/$(MODE)/tool/net/lsqlite3.o \
|
o/$(MODE)/tool/net/lsqlite3.o \
|
||||||
o/$(MODE)/tool/net/largon2.o \
|
o/$(MODE)/tool/net/largon2.o \
|
||||||
o/$(MODE)/tool/net/net.pkg \
|
o/$(MODE)/tool/net/net.pkg \
|
||||||
|
@ -225,6 +228,7 @@ o/$(MODE)/tool/net/redbean-unsecure.com: \
|
||||||
o/$(MODE)/tool/net/redbean-unsecure.com.dbg: \
|
o/$(MODE)/tool/net/redbean-unsecure.com.dbg: \
|
||||||
$(TOOL_NET_DEPS) \
|
$(TOOL_NET_DEPS) \
|
||||||
o/$(MODE)/tool/net/redbean-unsecure.o \
|
o/$(MODE)/tool/net/redbean-unsecure.o \
|
||||||
|
o/$(MODE)/tool/net/lmaxmind.o \
|
||||||
o/$(MODE)/tool/net/lsqlite3.o \
|
o/$(MODE)/tool/net/lsqlite3.o \
|
||||||
o/$(MODE)/tool/net/net.pkg \
|
o/$(MODE)/tool/net/net.pkg \
|
||||||
$(CRT) \
|
$(CRT) \
|
||||||
|
@ -254,7 +258,6 @@ o/$(MODE)/tool/net/redbean-original.com: \
|
||||||
o/$(MODE)/tool/net/redbean-original.com.dbg: \
|
o/$(MODE)/tool/net/redbean-original.com.dbg: \
|
||||||
$(TOOL_NET_DEPS) \
|
$(TOOL_NET_DEPS) \
|
||||||
o/$(MODE)/tool/net/redbean-original.o \
|
o/$(MODE)/tool/net/redbean-original.o \
|
||||||
o/$(MODE)/tool/net/lsqlite3.o \
|
|
||||||
o/$(MODE)/tool/net/net.pkg \
|
o/$(MODE)/tool/net/net.pkg \
|
||||||
$(CRT) \
|
$(CRT) \
|
||||||
$(APE)
|
$(APE)
|
||||||
|
|
|
@ -5811,6 +5811,7 @@ static const luaL_Reg kLuaFuncs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int luaopen_lsqlite3(lua_State *);
|
extern int luaopen_lsqlite3(lua_State *);
|
||||||
|
extern int LuaMaxmind(lua_State *);
|
||||||
|
|
||||||
#ifndef UNSECURE
|
#ifndef UNSECURE
|
||||||
extern int luaopen_argon2(lua_State *);
|
extern int luaopen_argon2(lua_State *);
|
||||||
|
@ -5818,6 +5819,7 @@ extern int luaopen_argon2(lua_State *);
|
||||||
|
|
||||||
static const luaL_Reg kLuaLibs[] = {
|
static const luaL_Reg kLuaLibs[] = {
|
||||||
{"re", LuaRe}, //
|
{"re", LuaRe}, //
|
||||||
|
{"maxmind", LuaMaxmind}, //
|
||||||
{"lsqlite3", luaopen_lsqlite3}, //
|
{"lsqlite3", luaopen_lsqlite3}, //
|
||||||
#ifndef UNSECURE
|
#ifndef UNSECURE
|
||||||
{"argon2", luaopen_argon2}, //
|
{"argon2", luaopen_argon2}, //
|
||||||
|
|
Loading…
Reference in a new issue