/* Adds a scalar field (NOT an enumeration) to the given structure. Fields may name-collide. */ int add_scalar_field(ParsedStruct *strct, char *name, ScalarTag field) { int i = strct->num_scalars; if (field == SCALAR_ENUM) return 0; /* This function is not for adding enumerated fields */ if (strct->num_scalars == strct->scalars_alloc) if (!realloc_struct_scalars(strct)) return 0; strct->scalars[i].name = util_strdup(name); if (!strct->scalars[i].name) return 0; strct->scalars[i].offset = strct->offset; strct->scalars[i].type.tag = field; strct->scalars[i].type.enum_type = NULL; strct->offset += field_length(field); strct->num_scalars++; return 1; }
inline void field_fill( const Scalar data, NgpFieldVector<Scalar> & xField, const stk::mesh::Selector selector, const MPI_Comm comm) { ThrowAssert(typeid(Scalar) == xField.get_field().data_traits().type_info); stk::mesh::BucketVector const& buckets = xField.get_buckets(selector); for(size_t i=0; i < buckets.size(); i++) { stk::mesh::Bucket & b = *buckets[i]; KokkosBLAS<Scalar>::fill(field_length(xField, b), data, field_ptr(xField, b)); } }
inline void field_asum( Scalar & glob_result, NgpFieldVector<Scalar>& xField, const stk::mesh::Selector& selector, const MPI_Comm comm) { ThrowAssert(typeid(Scalar) == xField.get_field().data_traits().type_info); stk::mesh::BucketVector const& buckets = xField.get_buckets(selector); KokkosVector& dev_x = xField.device_get(); Scalar local_result = Scalar(0.0); for(size_t i=0; i < buckets.size(); i++) { stk::mesh::Bucket & b = *buckets[i]; int kmax = field_length(xField, b); xField.copy_to_device(kmax, field_ptr(xField, b)); Scalar gpu_result = Scalar(0.0); Kokkos::parallel_reduce( range_policy( 0, kmax), KOKKOS_LAMBDA ( int k, double& update ) { update += dev_x( k ); }, gpu_result );
/** * Perform geographical lookup on target. */ int geo_lookup(modsec_rec *msr, geo_rec *georec, const char *target, char **error_msg) { apr_sockaddr_t *addr; long ipnum = 0; char *targetip = NULL; geo_db *geo = msr->txcfg->geo; char errstr[1024]; unsigned char buf[2* GEO_MAX_RECORD_LEN]; const int reclen = 3; /* Algorithm needs changed if this changes */ apr_size_t nbytes; unsigned int rec_val = 0; apr_off_t seekto = 0; apr_status_t ret; int rc; int country = 0; int level; double dtmp; int itmp; *error_msg = NULL; /* init */ georec->country_code = geo_country_code[0]; georec->country_code3 = geo_country_code3[0]; georec->country_name = geo_country_name[0]; georec->country_continent = geo_country_continent[0]; georec->region = ""; georec->city = ""; georec->postal_code = ""; georec->latitude = 0; georec->longitude = 0; georec->dma_code = 0; georec->area_code = 0; if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: Looking up \"%s\".", log_escape(msr->mp, target)); } /* NOTE: This only works with ipv4 */ if ((rc = apr_sockaddr_info_get(&addr, target, APR_INET, 0, 0, msr->mp)) != APR_SUCCESS) { *error_msg = apr_psprintf(msr->mp, "Geo lookup for \"%s\" failed: %s", log_escape(msr->mp, target), apr_strerror(rc, errstr, 1024)); msr_log(msr, 4, "%s", *error_msg); return 0; } if ((rc = apr_sockaddr_ip_get(&targetip, addr)) != APR_SUCCESS) { *error_msg = apr_psprintf(msr->mp, "Geo lookup for \"%s\" failed: %s", log_escape(msr->mp, target), apr_strerror(rc, errstr, 1024)); msr_log(msr, 4, "%s", *error_msg); return 0; }; /* Why is this in host byte order? */ ipnum = ntohl(addr->sa.sin.sin_addr.s_addr); if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: Using address \"%s\" (0x%08lx). %lu", targetip, ipnum, ipnum); } ret = apr_global_mutex_lock(msr->modsecurity->geo_lock); if (ret != APR_SUCCESS) { msr_log(msr, 1, "Geo Lookup: Failed to lock proc mutex: %s", get_apr_error(msr->mp, ret)); } for (level = 31; level >= 0; level--) { /* Read the record */ seekto = 2 * reclen * rec_val; apr_file_seek(geo->db, APR_SET, &seekto); /* TODO: check rc */ rc = apr_file_read_full(geo->db, &buf, (2 * reclen), &nbytes); /* NOTE: This is hard-coded for size 3 records */ /* Left */ if ((ipnum & (1 << level)) == 0) { rec_val = (buf[3*0 + 0] << (0*8)) + (buf[3*0 + 1] << (1*8)) + (buf[3*0 + 2] << (2*8)); } /* Right */ else { rec_val = (buf[3*1 + 0] << (0*8)) + (buf[3*1 + 1] << (1*8)) + (buf[3*1 + 2] << (2*8)); } /* If we are past the country offset, then we are done */ if (rec_val >= geo->ctry_offset) { break; } } if (rec_val == geo->ctry_offset) { *error_msg = apr_psprintf(msr->mp, "No geo data for \"%s\").", log_escape(msr->mp, target)); msr_log(msr, 4, "%s", *error_msg); ret = apr_global_mutex_unlock(msr->modsecurity->geo_lock); if (ret != APR_SUCCESS) { msr_log(msr, 1, "Geo Lookup: Failed to lock proc mutex: %s", get_apr_error(msr->mp, ret)); } return 0; } if (geo->dbtype == GEO_COUNTRY_DATABASE) { country = rec_val; country -= geo->ctry_offset; if ((country <= 0) || (country > GEO_COUNTRY_LAST)) { *error_msg = apr_psprintf(msr->mp, "No geo data for \"%s\" (country %d).", log_escape(msr->mp, target), country); msr_log(msr, 4, "%s", *error_msg); ret = apr_global_mutex_unlock(msr->modsecurity->geo_lock); if (ret != APR_SUCCESS) { msr_log(msr, 1, "Geo Lookup: Failed to lock proc mutex: %s", get_apr_error(msr->mp, ret)); } return 0; } /* Country */ georec->country_code = geo_country_code[country]; georec->country_code3 = geo_country_code3[country]; georec->country_name = geo_country_name[country]; georec->country_continent = geo_country_continent[country]; } else { int field_len = 0; int rec_offset = 0; int remaining = GEO_CITY_RECORD_LEN; unsigned char cbuf[GEO_CITY_RECORD_LEN]; seekto = rec_val + (2 * reclen - 1) * geo->ctry_offset; apr_file_seek(geo->db, APR_SET, &seekto); /* TODO: check rc */ rc = apr_file_read_full(geo->db, &cbuf, sizeof(cbuf), &nbytes); country = cbuf[0]; if ((country <= 0) || (country > GEO_COUNTRY_LAST)) { *error_msg = apr_psprintf(msr->mp, "No geo data for \"%s\" (country %d).", log_escape(msr->mp, target), country); msr_log(msr, 4, "%s", *error_msg); ret = apr_global_mutex_unlock(msr->modsecurity->geo_lock); if (ret != APR_SUCCESS) { msr_log(msr, 1, "Geo Lookup: Failed to lock proc mutex: %s", get_apr_error(msr->mp, ret)); } return 0; } if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: rec=\"%s\"", log_escape_raw(msr->mp, cbuf, sizeof(cbuf))); } /* Country */ if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: country=\"%.*s\"", (1*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))); } georec->country_code = geo_country_code[country]; georec->country_code3 = geo_country_code3[country]; georec->country_name = geo_country_name[country]; georec->country_continent = geo_country_continent[country]; rec_offset++; remaining -= rec_offset; /* Region */ field_len = field_length((const char *)cbuf+rec_offset, remaining); if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: region=\"%.*s\"", ((field_len+1)*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4)); } georec->region = apr_pstrmemdup(msr->mp, (const char *)cbuf+rec_offset, (remaining)); rec_offset += field_len + 1; remaining -= field_len + 1; /* City */ field_len = field_length((const char *)cbuf+rec_offset, remaining); if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: city=\"%.*s\"", ((field_len+1)*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4)); } georec->city = apr_pstrmemdup(msr->mp, (const char *)cbuf+rec_offset, (remaining)); rec_offset += field_len + 1; remaining -= field_len + 1; /* Postal Code */ field_len = field_length((const char *)cbuf+rec_offset, remaining); if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: postal_code=\"%.*s\"", ((field_len+1)*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4)); } georec->postal_code = apr_pstrmemdup(msr->mp, (const char *)cbuf+rec_offset, (remaining)); rec_offset += field_len + 1; remaining -= field_len + 1; /* Latitude */ if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: latitude=\"%.*s\"", (3*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4)); } dtmp = cbuf[rec_offset] + (cbuf[rec_offset+1] << 8) + (cbuf[rec_offset+2] << 16); georec->latitude = dtmp/10000 - 180; rec_offset += 3; remaining -= 3; /* Longitude */ if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: longitude=\"%.*s\"", (3*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4)); } dtmp = cbuf[rec_offset] + (cbuf[rec_offset+1] << 8) + (cbuf[rec_offset+2] << 16); georec->longitude = dtmp/10000 - 180; rec_offset += 3; remaining -= 3; /* dma/area codes are in city rev1 and US only */ if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "GEO: dma/area=\"%.*s\"", (3*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4)); } if (geo->dbtype == GEO_CITY_DATABASE_1 && georec->country_code[0] == 'U' && georec->country_code[1] == 'S') { /* DMA Code */ itmp = cbuf[rec_offset] + (cbuf[rec_offset+1] << 8) + (cbuf[rec_offset+2] << 16); georec->dma_code = itmp / 1000; georec->area_code = itmp % 1000; rec_offset += 6; remaining -= 6; } } *error_msg = apr_psprintf(msr->mp, "Geo lookup for \"%s\" succeeded.", log_escape(msr->mp, target)); ret = apr_global_mutex_unlock(msr->modsecurity->geo_lock); if (ret != APR_SUCCESS) { msr_log(msr, 1, "Geo Lookup: Failed to lock proc mutex: %s", get_apr_error(msr->mp, ret)); } return 1; }