From e4f65348cbc7da057d288d75743ce780af811e07 Mon Sep 17 00:00:00 2001 From: dmiller Date: Thu, 28 Jun 2018 03:43:25 +0000 Subject: [PATCH] Use lua_createtable to prealloc some tables, saving time & memory --- nse_main.cc | 2 +- nse_nmaplib.cc | 39 ++++++++++++++++++++++++--------------- nse_nmaplib.h | 2 ++ nse_ssl_cert.cc | 25 +++++++++++++++---------- 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/nse_main.cc b/nse_main.cc index b49e95c6c..223087214 100644 --- a/nse_main.cc +++ b/nse_main.cc @@ -105,7 +105,7 @@ static int ports (lua_State *L) while ((current = plist->nextPort(current, &port, TCPANDUDPANDSCTP, states[i])) != NULL) { - lua_newtable(L); + lua_createtable(L, 0, NSE_NUM_PORTINFO_FIELDS); set_portinfo(L, target, current); lua_pushboolean(L, 1); lua_rawset(L, -3); diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc index 5c56cf7c9..6e0b79b70 100644 --- a/nse_nmaplib.cc +++ b/nse_nmaplib.cc @@ -31,6 +31,10 @@ extern NmapOps o; static const char *NSE_PROTOCOL_OP[] = {"tcp", "udp", "sctp", NULL}; static const int NSE_PROTOCOL[] = {IPPROTO_TCP, IPPROTO_UDP, IPPROTO_SCTP}; +// Number of fields in the "version" table +// used as a hint to Lua when allocating it +#define NSE_NUM_VERSION_FIELDS 12 + void set_version (lua_State *L, const struct serviceDeductions *sd) { nseU_setsfield(L, -1, "name", sd->name); @@ -50,7 +54,7 @@ void set_version (lua_State *L, const struct serviceDeductions *sd) sd->dtype == SERVICE_DETECTION_TABLE ? "table" : sd->dtype == SERVICE_DETECTION_PROBED ? "probed" : NULL); - lua_newtable(L); + lua_createtable(L, sd->cpe.size(), 0); for (size_t i = 0; i < sd->cpe.size(); i++) { lua_pushstring(L, sd->cpe[i]); lua_rawseti(L, -2, i+1); @@ -73,7 +77,7 @@ void set_portinfo (lua_State *L, const Target *target, const Port *port) nseU_setsfield(L, -1, "state", statenum2str(port->state)); nseU_setsfield(L, -1, "reason", reason_str(port->reason.reason_id, 1)); nseU_setifield(L, -1, "reason_ttl", port->reason.ttl); - lua_newtable(L); + lua_createtable(L, 0, NSE_NUM_VERSION_FIELDS); set_version(L, &sd); lua_setfield(L, -2, "version"); } @@ -108,14 +112,15 @@ static void push_osclass_table(lua_State *L, const struct OS_Classification *osclass) { unsigned int i; - lua_newtable(L); +#define NSE_NUM_OSCLASS_FIELDS 5 + lua_createtable(L, 0, NSE_NUM_OSCLASS_FIELDS); set_string_or_nil(L, "vendor", osclass->OS_Vendor); set_string_or_nil(L, "osfamily", osclass->OS_Family); set_string_or_nil(L, "osgen", osclass->OS_Generation); set_string_or_nil(L, "type", osclass->Device_Type); - lua_newtable(L); + lua_createtable(L, osclass->cpe.size(), 0); for (i = 0; i < osclass->cpe.size(); i++) { lua_pushstring(L, osclass->cpe[i]); lua_rawseti(L, -2, i + 1); @@ -127,12 +132,13 @@ static void push_osmatch_table(lua_State *L, const FingerMatch *match, const OS_Classification_Results *OSR) { int i; - lua_newtable(L); +#define NSE_NUM_OSMATCH_FIELDS 2 + lua_createtable(L, 0, NSE_NUM_OSMATCH_FIELDS); lua_pushstring(L, match->OS_name); lua_setfield(L, -2, "name"); - lua_newtable(L); + lua_createtable(L, OSR->OSC_num_matches, 0); for (i = 0; i < OSR->OSC_num_matches; i++) { push_osclass_table(L, OSR->OSC[i]); lua_rawseti(L, -2, i + 1); @@ -181,7 +187,8 @@ void set_hostinfo(lua_State *L, Target *currenths) { push_bin_ip(L, currenths->SourceSockAddr()); lua_setfield(L, -2, "bin_ip_src"); - lua_newtable(L); +#define NSE_NUM_TIMES_FIELDS 3 + lua_createtable(L, 0, NSE_NUM_TIMES_FIELDS); nseU_setnfield(L, -1, "srtt", (lua_Number) currenths->to.srtt / 1000000.0); nseU_setnfield(L, -1, "rttvar", (lua_Number) currenths->to.rttvar / 1000000.0); nseU_setnfield(L, -1, "timeout", (lua_Number) currenths->to.timeout / 1000000.0); @@ -195,10 +202,11 @@ void set_hostinfo(lua_State *L, Target *currenths) { { std::list::iterator it; - lua_newtable(L); + lua_createtable(L, currenths->traceroute_hops.size(), 0); for (it = currenths->traceroute_hops.begin(); it != currenths->traceroute_hops.end(); it++) { - lua_newtable(L); +#define NSE_NUM_TRACEROUTE_FIELDS 3 + lua_createtable(L, 0, NSE_NUM_TRACEROUTE_FIELDS); /* fill the table if the hop has not timed out, otherwise an empty table * is inserted */ if (!it->timedout) { @@ -230,7 +238,7 @@ void set_hostinfo(lua_State *L, Target *currenths) { int i; const OS_Classification_Results *OSR = FPR->getOSClassification(); - lua_newtable(L); + lua_createtable(L, FPR->num_perfect_matches, 0); for (i = 0; i < FPR->num_perfect_matches; i++) { push_osmatch_table(L, FPR->matches[i], OSR); lua_rawseti(L, -2, i + 1); @@ -460,7 +468,7 @@ static int l_get_ports (lua_State *L) if (!(p = target->ports.nextPort(p, &port, protocol, state))) { lua_pushnil(L); } else { - lua_newtable(L); + lua_createtable(L, 0, NSE_NUM_PORTINFO_FIELDS); set_portinfo(L, target, p); } return 1; @@ -487,7 +495,7 @@ static int l_get_port_state (lua_State *L) lua_pushnil(L); else { - lua_newtable(L); + lua_createtable(L, 0, NSE_NUM_PORTINFO_FIELDS); set_portinfo(L, target, p); } return 1; @@ -791,7 +799,7 @@ static int l_get_dns_servers (lua_State *L) std::list servs2 = get_dns_servers(); std::list::iterator servI2; - lua_newtable(L); + lua_createtable(L, servs2.size(), 0); for (servI2 = servs2.begin(); servI2 != servs2.end(); servI2++) nseU_appendfstr(L, -1, "%s", servI2->c_str()); return 1; @@ -882,10 +890,11 @@ static int l_list_interfaces (lua_State *L) memset(ipstr, 0, INET6_ADDRSTRLEN); memset(&src, 0, sizeof(src)); memset(&bcast, 0, sizeof(bcast)); - lua_newtable(L); //base table + lua_createtable(L, numifs, 0); //base table for(i=0; i< numifs; i++) { - lua_newtable(L); //interface table +#define NSE_NUM_INTERFACE_FIELDS 9 + lua_createtable(L, 0, NSE_NUM_INTERFACE_FIELDS); //interface table nseU_setsfield(L, -1, "device", iflist[i].devfullname); nseU_setsfield(L, -1, "shortname", iflist[i].devname); nseU_setifield(L, -1, "netmask", iflist[i].netmask_bits); diff --git a/nse_nmaplib.h b/nse_nmaplib.h index de8fdeeec..848809ff4 100644 --- a/nse_nmaplib.h +++ b/nse_nmaplib.h @@ -7,7 +7,9 @@ class Target; class Port; int luaopen_nmap(lua_State* l); +#define NSE_NUM_HOSTINFO_FIELDS 17 void set_hostinfo(lua_State* l, Target* currenths); +#define NSE_NUM_PORTINFO_FIELDS 7 void set_portinfo(lua_State* l, const Target *target, const Port* port); #endif diff --git a/nse_ssl_cert.cc b/nse_ssl_cert.cc index 3ccee5d0f..dc9646c4e 100644 --- a/nse_ssl_cert.cc +++ b/nse_ssl_cert.cc @@ -265,7 +265,7 @@ static void x509_name_to_table(lua_State *L, X509_NAME *name) { int i; - lua_newtable(L); + lua_createtable(L, 0, X509_NAME_entry_count(name)); for (i = 0; i < X509_NAME_entry_count(name); i++) { X509_NAME_ENTRY *entry; @@ -288,7 +288,7 @@ static bool x509_extensions_to_table(lua_State *L, const STACK_OF(X509_EXTENSION if (sk_X509_EXTENSION_num(exts) <= 0) return false; - lua_newtable(L); + lua_createtable(L, sk_X509_EXTENSION_num(exts), 0); for (int i = 0; i < sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; @@ -299,7 +299,8 @@ static bool x509_extensions_to_table(lua_State *L, const STACK_OF(X509_EXTENSION ext = sk_X509_EXTENSION_value(exts, i); obj = X509_EXTENSION_get_object(ext); - lua_newtable(L); +#define NSE_NUM_X509_EXTENSION_FIELDS 3 + lua_createtable(L, 0, NSE_NUM_X509_EXTENSION_FIELDS); char objname[256]; long len = 0; len = OBJ_obj2txt(objname, 256, obj, 0); @@ -324,7 +325,7 @@ static bool x509_extensions_to_table(lua_State *L, const STACK_OF(X509_EXTENSION } BIO_free_all(out); - lua_seti(L, -2, i+1); + lua_rawseti(L, -2, i+1); } return true; @@ -418,7 +419,8 @@ static int time_to_tm(const ASN1_TIME *t, struct tm *result) that the wday and yday fields are not present. */ static void tm_to_table(lua_State *L, const struct tm *tm) { - lua_newtable(L); +#define NSE_NUM_TM_FIELDS 6 + lua_createtable(L, 0, NSE_NUM_TM_FIELDS); lua_pushnumber(L, tm->tm_year); lua_setfield(L, -2, "year"); @@ -459,7 +461,8 @@ static void asn1_time_to_obj(lua_State *L, const ASN1_TIME *s) from asn1_time_to_obj. */ static void x509_validity_to_table(lua_State *L, X509 *cert) { - lua_newtable(L); +#define NSE_NUM_VALIDITY_FIELDS 2 + lua_createtable(L, 0, NSE_NUM_VALIDITY_FIELDS); asn1_time_to_obj(L, X509_get0_notBefore(cert)); lua_setfield(L, -2, "notBefore"); @@ -512,8 +515,8 @@ int lua_push_ecdhparams(lua_State *L, EVP_PKEY *pubkey) { const EC_GROUP *group = EC_KEY_get0_group(ec_key); int nid; /* This structure (ecdhparams.curve_params) comes from tls.lua */ - lua_newtable(L); /* ecdhparams */ - lua_newtable(L); /* curve_params */ + lua_createtable(L, 0, 1); /* ecdhparams */ + lua_createtable(L, 0, 2); /* curve_params */ if ((nid = EC_GROUP_get_curve_name(group)) != 0) { lua_pushstring(L, OBJ_nid2sn(nid)); lua_setfield(L, -2, "curve"); @@ -591,7 +594,8 @@ static int parse_ssl_cert(lua_State *L, X509 *cert) udata = (struct cert_userdata *) lua_newuserdata(L, sizeof(*udata)); udata->cert = cert; - lua_newtable(L); +#define NSE_NUM_CERT_FIELDS 7 + lua_createtable(L, 0, NSE_NUM_CERT_FIELDS); subject = X509_get_subject_name(cert); if (subject != NULL) { @@ -633,7 +637,8 @@ static int parse_ssl_cert(lua_State *L, X509 *cert) lua_pushfstring(L, "Error parsing cert: %s", ERR_error_string(ERR_get_error(), NULL)); return 2; } - lua_newtable(L); +#define NSE_NUM_PKEY_FIELDS 4 + lua_createtable(L, 0, NSE_NUM_PKEY_FIELDS); #if HAVE_OPAQUE_STRUCTS pkey_type = EVP_PKEY_base_id(pubkey); #else