VCL_VOID vmod_resp(VRT_CTX, VCL_STRING val) { //thread check if(ctx->req == NULL || ctx->req->magic != REQ_MAGIC){ VSLb(ctx->vsl, SLT_Error,"vmod-dump: dump.resp work only at client-thread."); return; } VSLb(ctx->vsl, SLT_Debug,"%s-I: %s %d %s %d", VMOD_DUMP_PRE, VRT_IP_string(ctx, VRT_r_client_ip(ctx)), VSA_Port(VRT_r_client_ip(ctx)), VRT_IP_string(ctx, VRT_r_server_ip(ctx)), VSA_Port(VRT_r_server_ip(ctx)) ); VDP_push(ctx->req, VDP_dump, (void*)val, 1); }
/* Returns the GeoIP info as synthetic response */ void vcl_geoip_send_synthetic(const struct sess *sp) { vcl_string hval[HEADER_MAXLEN]; vcl_string *ip = VRT_IP_string(sp, VRT_r_client_ip(sp)); if (geoip_lookup(ip, hval)) { VRT_synth_page(sp, 0, hval, vrt_magic_string_end); } else { VRT_synth_page(sp, 0, "", vrt_magic_string_end); } }
/* Sets "X-Geo-IP" header with the geoip resolved information */ void vcl_geoip_set_header(const struct sess *sp) { vcl_string hval[HEADER_MAXLEN]; vcl_string *ip = VRT_IP_string(sp, VRT_r_client_ip(sp)); if (geoip_lookup(ip, hval)) { VRT_SetHdr(sp, HDR_REQ, "\011X-Geo-IP:", hval, vrt_magic_string_end); } else { /* Send an empty header */ VRT_SetHdr(sp, HDR_REQ, "\011X-Geo-IP:", "", vrt_magic_string_end); } }
VCL_VOID vmod_req(VRT_CTX, VCL_STRING val) { //thread check if(ctx->req == NULL || ctx->req->magic != REQ_MAGIC){ VSLb(ctx->vsl, SLT_Error,"vmod-dump: dump.req work only at client-thread."); return; } //remote client local server //VRT_r_remote_ip //VRT_r_client_ip //VRT_r_local_ip //VRT_r_server_ip //VRT_IP_string(IP) ip->str //VSA_Port(IP) ip->port VSLb(ctx->vsl, SLT_Debug,"%s-I: %s %d %s %d", VMOD_DUMP_PRE, VRT_IP_string(ctx, VRT_r_client_ip(ctx)), VSA_Port(VRT_r_client_ip(ctx)), VRT_IP_string(ctx, VRT_r_server_ip(ctx)), VSA_Port(VRT_r_server_ip(ctx)) ); VSLb(ctx->vsl, SLT_Debug,"%s-S: REQ", VMOD_DUMP_PRE); VSLb(ctx->vsl, SLT_Debug,"%s-V: %s", VMOD_DUMP_PRE, val); unsigned u; //reserve work-space u = WS_Reserve(ctx->req->ws, 0); if(u <= VMOD_DUMP_KEY_LEN) { //no space. WS_Release(ctx->req->ws, 0); return; } work_head(ctx->req,ctx->req->ws->f, u, ctx->req->http0,HTTP1_Req); //free work-space WS_Release(ctx->req->ws, 0); VRB_Iterate(ctx->req, vbf_printRequestBody, NULL); VSLb(ctx->vsl, SLT_Debug,"%s-S: END", VMOD_DUMP_PRE); }
VCL_STRING vmod_country_code_from_ip(const struct vrt_ctx* ctx, struct vmod_priv* pp, const struct suckaddr* ip) { return vmod_country(ctx, pp, VRT_IP_string(ctx, ip)); }
VCL_STRING vmod_region_from_ip(const struct vrt_ctx* ctx, struct vmod_priv* pp, const struct suckaddr* ip) { return vmod_region(ctx, pp, VRT_IP_string(ctx, ip)); }
/* Simplified version: sets "X-Geo-IP" header with the country only */ void vcl_geoip_country_set_header(const struct sess *sp) { vcl_string hval[HEADER_MAXLEN]; vcl_string *ip = VRT_IP_string(sp, VRT_r_client_ip(sp)); geoip_lookup_country(ip, hval); VRT_SetHdr(sp, HDR_REQ, "\011X-Geo-IP:", hval, vrt_magic_string_end); }
vmod_geoip2_lookup(VRT_CTX, struct vmod_geoip2_geoip2 *vp, VCL_STRING path, VCL_IP addr) { MMDB_lookup_result_s res; MMDB_entry_data_s data; const struct sockaddr *sa; socklen_t addrlen; const char **ap, *arrpath[COMPONENT_MAX]; char buf[LOOKUP_PATH_MAX]; char *p, *last; uint32_t i; int error; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(addr); if (!vp) { VSLb(ctx->vsl, SLT_Error, "geoip2.lookup: Database not open"); return (NULL); } if (!path || !*path || strlen(path) >= sizeof(buf)) { VSLb(ctx->vsl, SLT_Error, "geoip2.lookup: Invalid or missing path (%s)", path ? path : "NULL"); return (NULL); } sa = VSA_Get_Sockaddr(addr, &addrlen); AN(sa); res = MMDB_lookup_sockaddr(&vp->mmdb, sa, &error); if (error != MMDB_SUCCESS) { VSLb(ctx->vsl, SLT_Error, "geoip2.lookup: MMDB_lookup_sockaddr: %s", MMDB_strerror(error)); return (NULL); } if (!res.found_entry) { VSLb(ctx->vsl, SLT_Debug, "geoip2.lookup: No entry for this IP address (%s)", VRT_IP_string(ctx, addr)); return (NULL); } strncpy(buf, path, sizeof(buf)); last = NULL; for (p = buf, ap = arrpath; ap < &arrpath[COMPONENT_MAX - 1] && (*ap = strtok_r(p, "/", &last)) != NULL; p = NULL) { if (**ap != '\0') ap++; } *ap = NULL; error = MMDB_aget_value(&res.entry, &data, arrpath); if (error != MMDB_SUCCESS && error != MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR) { VSLb(ctx->vsl, SLT_Error, "geoip2.lookup: MMDB_aget_value: %s", MMDB_strerror(error)); return (NULL); } if (!data.has_data) { VSLb(ctx->vsl, SLT_Debug, "geoip2.lookup: No data for this path (%s)", path); return (NULL); } switch (data.type) { case MMDB_DATA_TYPE_BOOLEAN: p = WS_Printf(ctx->ws, "%s", data.boolean ? "true" : "false"); break; case MMDB_DATA_TYPE_BYTES: p = WS_Alloc(ctx->ws, data.data_size * 2 + 1); if (p) for (i = 0; i < data.data_size; i++) sprintf(&p[i * 2], "%02X", data.bytes[i]); break; case MMDB_DATA_TYPE_DOUBLE: p = WS_Printf(ctx->ws, "%f", data.double_value); break; case MMDB_DATA_TYPE_FLOAT: p = WS_Printf(ctx->ws, "%f", data.float_value); break; case MMDB_DATA_TYPE_INT32: p = WS_Printf(ctx->ws, "%i", data.int32); break; case MMDB_DATA_TYPE_UINT16: p = WS_Printf(ctx->ws, "%u", data.uint16); break; case MMDB_DATA_TYPE_UINT32: p = WS_Printf(ctx->ws, "%u", data.uint32); break; case MMDB_DATA_TYPE_UINT64: p = WS_Printf(ctx->ws, "%ju", (uintmax_t)data.uint64); break; case MMDB_DATA_TYPE_UTF8_STRING: p = WS_Alloc(ctx->ws, data.data_size + 1); if (p) { memcpy(p, data.utf8_string, data.data_size); p[data.data_size] = '\0'; } break; default: VSLb(ctx->vsl, SLT_Error, "geoip2.lookup: Unsupported data type (%d)", data.type); return (NULL); } if (!p) VSLb(ctx->vsl, SLT_Error, "geoip2.lookup: Out of workspace"); return (p); }