/* #!/usr/bin/env zsh for i in $(ls *.c) do basename=$(echo ${i}|awk -F '.' '{ print $1}') sudo -u haproxy cc -I/usr/include/ -I/usr/include/lua5.3/ -fPIC -shared -o ${basename}.so ${i} -lcurl -ljansson -lmaxminddb done */ #include #include #include #include #include #include #include #include #include #include static MMDB_s* mmdb; static int load_geoip(lua_State *L) { const char *filename = luaL_checkstring(L, 1); int status; mmdb = malloc(sizeof (struct MMDB_s)); status = MMDB_open(filename, MMDB_MODE_MMAP, mmdb); if (status != 0) { printf("Error loading geoip database\n"); exit(1); } else { printf("Loaded geoip database at: %s\n", filename); } return 0; } int get_geoip_info(const char* ip_address, MMDB_lookup_result_s* result) { int gai_error, mmdb_error; (*result) = MMDB_lookup_string(mmdb, ip_address, &gai_error, &mmdb_error); if (0 != gai_error) { fprintf(stderr, "\n Error from getaddrinfo for %s - %s\n\n", ip_address, gai_strerror(gai_error)); exit(2); } if (MMDB_SUCCESS != mmdb_error) { fprintf(stderr, "\n Got an error from libmaxminddb: %s\n\n", MMDB_strerror(mmdb_error)); exit(3); } return 0; } int filter_value( bool found_entry, MMDB_entry_s* entry, MMDB_entry_data_list_s* entry_data_list, MMDB_entry_data_s* entry_data, const char* query) { int status; MMDB_get_entry_data_list(entry, &entry_data_list); MMDB_free_entry_data_list(entry_data_list); if (found_entry) { if (strcmp(query, "country") == 0) { status = MMDB_get_value(entry, entry_data, "country", "iso_code", NULL); return status; } else if (strcmp(query, "city") == 0){ status = MMDB_get_value(entry, entry_data, "city", "names", "en", NULL); return status; } } return 1; } static int get_country(lua_State *L) { const char *ip_address = luaL_checkstring(L, 1); char* country = malloc(4); int status; MMDB_entry_data_list_s *entry_data_list = malloc(sizeof (struct MMDB_entry_data_list_s)); MMDB_entry_data_s* entry_data = malloc(sizeof (struct MMDB_entry_data_s)); MMDB_lookup_result_s* result = malloc(sizeof (struct MMDB_lookup_result_s)); status = get_geoip_info(ip_address, result); status = filter_value(result->found_entry, &result->entry, entry_data_list, entry_data, "country"); free(result); result = NULL; if (status == 0) { sprintf(country, "%.*s", entry_data->data_size, entry_data->utf8_string); } else { strcpy(country, "N/A"); } lua_pushstring(L, country); return 1; } static int get_city(lua_State *L) { const char *ip_address = luaL_checkstring(L, 1); char* city = malloc(50); int status; MMDB_entry_data_list_s *entry_data_list = malloc(sizeof (struct MMDB_entry_data_list_s)); MMDB_entry_data_s* entry_data = malloc(sizeof (struct MMDB_entry_data_s)); MMDB_lookup_result_s* result = malloc(sizeof (struct MMDB_lookup_result_s)); status = get_geoip_info(ip_address, result); status = filter_value(result->found_entry, &result->entry, entry_data_list, entry_data, "city"); free(result); result = NULL; if (status == 0) { sprintf(city, "%.*s", entry_data->data_size, entry_data->utf8_string); } else { strcpy(city, "not found"); } free(entry_data); entry_data = NULL; lua_pushstring(L, city); free(city); city = NULL; return 1; } static int download_file() { return 0; } static int request(lua_State *L) { const char *url = luaL_checkstring(L, 1); CURL *curl = curl_easy_init(); if (curl) { CURLcode res; curl_easy_setopt(curl, CURLOPT_URL, url); res = curl_easy_perform(curl); curl_easy_cleanup(curl); } return 0; } /* static void stackDump(lua_State *L) { int i; int top = lua_gettop(L); for(i = 1; i <= top; i++) { int t = lua_type(L, i); switch(t) { case LUA_TNIL: printf("nil"); break; case LUA_TBOOLEAN: printf(lua_toboolean(L, i) ? "true" : "false"); break; case LUA_TNUMBER: printf("%g", lua_tonumber(L, i)); break; case LUA_TSTRING: printf("%s", lua_tostring(L, i)); break; default: printf("%s", lua_typename(L, t)); } printf(" "); } printf("\n\n"); }*/ int get_info(lua_State *L) { lua_getglobal(L, "core"); lua_getfield(L, -1, "get_info"); int err = lua_pcall(L, 0, 1, 0); if (err == 0) { lua_getfield(L, -1, "Build info"); const char *version = lua_tostring(L, -1); printf("HAProxy version: %s\n",version); } else { printf("%d %s\n", err, lua_tostring(L, -1)); } return 0; } int luaopen_haproxy(lua_State *L) { printf("Loading C lua module\n"); lua_pushcfunction(L, load_geoip); lua_setglobal(L, "load_geoip"); lua_pushcfunction(L, get_country); lua_setglobal(L, "get_country"); lua_pushcfunction(L, get_city); lua_setglobal(L, "get_city"); lua_pushcfunction(L, request); lua_setglobal(L, "request"); return 0; }