1- /*
2- * IP2Proxy Varnish library is distributed under LGPL version 3
3- * Copyright (c) 2013-2019 IP2Proxy.com. support at ip2location dot com
4- *
5- * This library is free software; you can redistribute it and/or
6- * modify it under the terms of the GNU Lesser General Public
7- * License as published by the Free Software Foundation; either
8- * version 3 of the License, or any later version.
9- *
10- * This library is distributed in the hope that it will be useful,
11- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13- * Lesser General Public License for more details.
14- *
15- * You should have received a copy of the GNU Lesser General Public
16- * License along with this library; if not see <http://www.gnu.org/licenses/>.
17- *
18- */
191#include <stdlib.h>
202#include <string.h>
21-
223#include <IP2Proxy.h>
234
5+ #include <sys/types.h>
6+ #include <sys/stat.h>
7+ #include <unistd.h>
8+ #include <pthread.h>
9+
10+ #ifdef __FreeBSD__
11+ #include <stdio.h>
12+ #define gcvt (v , d , c ) sprintf(c, "%*g", d, v);
13+ #endif
14+
2415#include "cache/cache.h"
2516
26- static void
27- ip2proxy_free (void * ptr )
17+ /* Varnish < 6.2 compat */
18+ #ifndef VPFX
19+ # define VPFX (a ) vmod_ ## a
20+ # define VARGS (a ) vmod_ ## a ## _arg
21+ # define VENUM (a ) vmod_enum_ ## a
22+ # define VEVENT (a ) a
23+ #else
24+ # define VEVENT (a ) VPFX(a)
25+ #endif
26+
27+ #ifndef VRT_H_INCLUDED
28+ #include "vrt.h"
29+ #endif
30+
31+ /* Defined options for querying IP2Proxy data */
32+ #define query_COUNTRY_SHORT 1
33+ #define query_COUNTRY_LONG 2
34+ #define query_REGION 3
35+ #define query_CITY 4
36+ #define query_ISP 5
37+ #define query_DOMAIN 6
38+ #define query_USAGETYPE 7
39+ #define query_PROXYTYPE 8
40+ #define query_ASN 9
41+ #define query_AS 10
42+ #define query_LASTSEEN 11
43+ #define query_ISPROXY 12
44+ #define query_THREAT 13
45+
46+ typedef struct vmod_ip2proxy_data {
47+ time_t ip2p_db_ts ; /* timestamp of the database file */
48+ IP2Proxy * ip2p_handle ;
49+ pthread_mutex_t lock ;
50+ } ip2proxy_data_t ;
51+
52+ void
53+ ip2p_free (void * d )
2854{
29- IP2Proxy_close ((IP2Proxy * )ptr );
55+ ip2proxy_data_t * data = d ;
56+
57+ if (data -> ip2p_handle != NULL ) {
58+ IP2Proxy_close (data -> ip2p_handle );
59+ }
3060}
3161
3262VCL_VOID
33- vmod_init_db ( VRT_CTX , struct vmod_priv * priv , char * filename , char * memtype )
63+ VPFX ( init_db )( VRT_CTX , struct VPFX ( priv ) * priv , char * filename , char * memtype )
3464{
35- IP2Proxy * IP2ProxyObj ;
36- enum IP2Proxy_mem_type mtype ;
37-
3865 CHECK_OBJ_NOTNULL (ctx , VRT_CTX_MAGIC );
39- AN (priv );
40- AN (memtype );
41-
42- if (strcmp (memtype , "IP2PROXY_FILE_IO" ) == 0 )
43- mtype = IP2PROXY_FILE_IO ;
44- else if (strcmp (memtype , "IP2PROXY_SHARED_MEMORY" ) == 0 )
45- mtype = IP2PROXY_SHARED_MEMORY ;
46- else if (strcmp (memtype , "IP2PROXY_CACHE_MEMORY" ) == 0 )
47- mtype = IP2PROXY_CACHE_MEMORY ;
48- else {
49- VRT_fail (ctx , "IP2Proxy: invalid memtype (%s)" , memtype );
50- return ;
66+
67+ if (priv -> priv == NULL ) {
68+ IP2Proxy * IP2ProxyObj = IP2Proxy_open ((char * ) filename );
69+
70+ if (IP2ProxyObj == NULL ) {
71+ printf ("Not able to load IP2Proxy Database \"%s\".\n" , (char * ) filename );
72+
73+ exit (0 );
74+ }
75+
76+ printf ("IP2Proxy Database %s is loaded.\n" , (char * ) filename );
77+
78+ priv -> priv = IP2ProxyObj ;
79+
80+ if (strcmp (memtype , "IP2PROXY_FILE_IO" ) == 0 ) {
81+ IP2Proxy_set_lookup_mode (priv -> priv , IP2PROXY_FILE_IO );
82+ } else if (strcmp (memtype , "IP2PROXY_CACHE_MEMORY" ) == 0 ) {
83+ IP2Proxy_set_lookup_mode (priv -> priv , IP2PROXY_CACHE_MEMORY );
84+ } else if (strcmp (memtype , "IP2PROXY_SHARED_MEMORY" ) == 0 ) {
85+ IP2Proxy_set_lookup_mode (priv -> priv , IP2PROXY_SHARED_MEMORY );
86+ }
87+
88+ AN (priv -> priv );
89+ priv -> free = ip2p_free ;
5190 }
91+ }
92+
93+ // Use this function to query result, and then extract the field based on user selection
94+ void *
95+ query_all (VRT_CTX , struct VPFX (priv ) * priv , char * ip , int option )
96+ {
97+ IP2ProxyRecord * r ;
98+ IP2Proxy * handle ;
99+ char * result = NULL ;
100+
101+ printf ("The client IP is %s.\n" , (char * ) ip );
102+
103+ CHECK_OBJ_NOTNULL (ctx , VRT_CTX_MAGIC );
104+
105+ if (priv -> priv != NULL ) {
106+ handle = priv -> priv ;
107+ r = IP2Proxy_get_all (handle , (char * ) ip );
108+
109+ if (r != NULL ) {
110+ switch (option ) {
111+ case query_COUNTRY_SHORT :
112+ result = WS_Copy (ctx -> ws , r -> country_short , -1 );
113+ break ;
114+ case query_COUNTRY_LONG :
115+ result = WS_Copy (ctx -> ws , r -> country_long , -1 );
116+ break ;
117+ case query_REGION :
118+ result = WS_Copy (ctx -> ws , r -> region , -1 );
119+ break ;
120+ case query_CITY :
121+ result = WS_Copy (ctx -> ws , r -> city , -1 );
122+ break ;
123+ case query_ISP :
124+ result = WS_Copy (ctx -> ws , r -> isp , -1 );
125+ break ;
126+ case query_DOMAIN :
127+ result = WS_Copy (ctx -> ws , r -> domain , -1 );
128+ break ;
129+ case query_USAGETYPE :
130+ result = WS_Copy (ctx -> ws , r -> usage_type , -1 );
131+ break ;
132+ case query_PROXYTYPE :
133+ result = WS_Copy (ctx -> ws , r -> proxy_type , -1 );
134+ break ;
135+ case query_ASN :
136+ result = WS_Copy (ctx -> ws , r -> asn , -1 );
137+ break ;
138+ case query_AS :
139+ result = WS_Copy (ctx -> ws , r -> as_ , -1 );
140+ break ;
141+ case query_LASTSEEN :
142+ result = WS_Copy (ctx -> ws , r -> last_seen , -1 );
143+ break ;
144+ case query_ISPROXY :
145+ result = WS_Copy (ctx -> ws , r -> is_proxy , -1 );
146+ break ;
147+ case query_THREAT :
148+ result = WS_Copy (ctx -> ws , r -> threat , -1 );
149+ break ;
150+ default :
151+ result = WS_Copy (ctx -> ws , "-" , -1 );
152+ break ;
153+ }
52154
53- if (priv -> priv != NULL )
54- IP2Proxy_close ((IP2Proxy * )priv -> priv );
155+ IP2Proxy_free_record (r );
55156
56- IP2ProxyObj = IP2Proxy_open (filename );
57- if (!IP2ProxyObj ) {
58- VRT_fail (ctx , "IP2Proxy: can't open database (%s)" , filename );
59- return ;
157+ return (result );
158+ }
60159 }
61- IP2Proxy_open_mem (IP2ProxyObj , mtype );
62160
63- priv -> priv = IP2ProxyObj ;
64- priv -> free = ip2proxy_free ;
161+ // VMOD_LOG("ERROR: IP2Proxy database failed to load");
162+
163+ return WS_Copy (ctx -> ws , "????" , -1 );
65164}
66165
67- #define FUNC (lower , field ) \
68- VCL_STRING \
69- vmod_ ## lower(VRT_CTX, struct vmod_priv *priv, char * ip) \
70- { \
71- char *result; \
72- IP2ProxyRecord *r; \
73- \
74- CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \
75- AN(priv); \
76- \
77- if (!ip || !priv->priv) \
78- return ("-"); \
79- \
80- r = IP2Proxy_get_all((IP2Proxy *)priv->priv, ip); \
81- if (!r) \
82- return ("-"); \
83- \
84- result = WS_Copy(ctx->ws, r->field, -1); \
85- IP2Proxy_free_record(r); \
86- \
87- return (result); \
166+ VCL_STRING
167+ VPFX (country_short )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
168+ {
169+ const char * result = NULL ;
170+ result = query_all (ctx , priv , ip , query_COUNTRY_SHORT );
171+ return (result );
88172}
89173
90- FUNC (country_short , country_short )
91- FUNC (country_long , country_long )
92- FUNC (region , region )
93- FUNC (city , city )
94- FUNC (isp , isp )
95- FUNC (domain , domain )
96- FUNC (usage_type , usage_type )
97- FUNC (proxy_type , proxy_type )
98- FUNC (asn , asn )
99- FUNC (as , as_ )
100- FUNC (last_seen , last_seen )
101- FUNC (is_proxy , is_proxy )
174+ VCL_STRING
175+ VPFX (country_long )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
176+ {
177+ const char * result = NULL ;
178+ result = query_all (ctx , priv , ip , query_COUNTRY_LONG );
179+ return (result );
180+ }
181+
182+ VCL_STRING
183+ VPFX (region )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
184+ {
185+ const char * result = NULL ;
186+ result = query_all (ctx , priv , ip , query_REGION );
187+ return (result );
188+ }
189+
190+ VCL_STRING
191+ VPFX (city )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
192+ {
193+ const char * result = NULL ;
194+ result = query_all (ctx , priv , ip , query_CITY );
195+ return (result );
196+ }
197+
198+ VCL_STRING
199+ VPFX (isp )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
200+ {
201+ const char * result = NULL ;
202+ result = query_all (ctx , priv , ip , query_ISP );
203+ return (result );
204+ }
205+
206+ VCL_STRING
207+ VPFX (domain )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
208+ {
209+ const char * result = NULL ;
210+ result = query_all (ctx , priv , ip , query_DOMAIN );
211+ return (result );
212+ }
213+
214+ VCL_STRING
215+ VPFX (usage_type )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
216+ {
217+ const char * result = NULL ;
218+ result = query_all (ctx , priv , ip , query_USAGETYPE );
219+ return (result );
220+ }
221+
222+ VCL_STRING
223+ VPFX (proxy_type )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
224+ {
225+ const char * result = NULL ;
226+ result = query_all (ctx , priv , ip , query_PROXYTYPE );
227+ return (result );
228+ }
229+
230+ VCL_STRING
231+ VPFX (asn )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
232+ {
233+ const char * result = NULL ;
234+ result = query_all (ctx , priv , ip , query_ASN );
235+ return (result );
236+ }
237+
238+ VCL_STRING
239+ VPFX (as )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
240+ {
241+ const char * result = NULL ;
242+ result = query_all (ctx , priv , ip , query_AS );
243+ return (result );
244+ }
245+
246+ VCL_STRING
247+ VPFX (last_seen )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
248+ {
249+ const char * result = NULL ;
250+ result = query_all (ctx , priv , ip , query_LASTSEEN );
251+ return (result );
252+ }
253+
254+ VCL_STRING
255+ VPFX (is_proxy )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
256+ {
257+ const char * result = NULL ;
258+ result = query_all (ctx , priv , ip , query_ISPROXY );
259+ return (result );
260+ }
261+
262+ VCL_STRING
263+ VPFX (threat )(VRT_CTX , struct VPFX (priv ) * priv , char * ip )
264+ {
265+ const char * result = NULL ;
266+ result = query_all (ctx , priv , ip , query_THREAT );
267+ return (result );
268+ }
0 commit comments