void engine::expand_class_instance ( cs::lua_debugger::backend& backend, cs::lua_debugger::value_to_expand& value_to_expand, lua_State* const state ) { typedef luabind::detail::object_rep object_rep; object_rep *object = luabind::detail::is_class_object(state,-1); VERIFY2 (object, "invalid object userdata"); if (object->crep()) { luabind::detail::class_rep *class_rep = object->crep(); string4096 type; class_name (type, sizeof(type), *class_rep); cs::lua_debugger::icon_type icon_type; string4096 value; backend.value_to_string (value, sizeof(value), state, -1, icon_type, true); value_to_expand.add_value ( class_rep->name(), type, value, cs::lua_debugger::icon_type_class ); } typedef luabind::detail::lua_reference lua_reference; lua_reference const &tbl = object->get_lua_table(); if (!tbl.is_valid()) return; tbl.get (state); int i; lua_pushnil (state); for (i=0; lua_next(state,-2); ++i) { cs::lua_debugger::icon_type icon_type; bool use_in_description; pcstr name = lua_to_string(state,-2); string4096 type; backend.type_to_string (type, sizeof(type), state, -1, use_in_description); string4096 value; backend.value_to_string (value, sizeof(value), state, -1, icon_type, true); value_to_expand.add_value ( name, type, value, icon_type ); lua_pop_value (state, 1); } lua_pop_value (state, 1); }
bool engine::value_convert_instance (cs::lua_debugger::backend& backend, char* buffer, unsigned int size, luabind::detail::object_rep *object, lua_State* state) { typedef luabind::detail::lua_reference lua_reference; lua_reference const &tbl = object->get_lua_table(); if (!tbl.is_valid()) return (false); pstr stream = buffer; stream += sprintf_s(stream, size - (stream - buffer), "{"); tbl.get (state); int i; lua_pushnil (state); for (i=0; lua_next(state,-2); ++i) { if (i == 3) { lua_pop_value (state, 2); stream += sprintf_s(stream, size - (stream - buffer), "..."); break; } pcstr name = lua_to_string(state,-2); string4096 type; bool use_in_description; backend.type_to_string (type, sizeof(type), state, -1, use_in_description); string4096 value; cs::lua_debugger::icon_type icon_type; backend.value_to_string (value, sizeof(value), state, -1, icon_type, false); if (use_in_description) stream += sprintf_s(stream, size - (stream - buffer), "%s[%s]=%s ", name, type, value); else stream += sprintf_s(stream, size - (stream - buffer), "%s=%s ", name, value); lua_pop_value (state, 1); } lua_pop_value (state, 1); if (!i) return (false); stream += sprintf_s(stream, size - (stream - buffer), "}%c",0); return (true); }
static int parse_single_var(char *val, size_t len, const char *name) { struct var *match; match = var_lookup(name); if (match) { if (strlen(match->val) + 1 > len) { set_errf("Variables '%s' with value '%s' is too long\n", match->name, match->val); return -1; } strncpy(val, match->val, len); return 0; } else { /* name + 1 to skip leading '$' */ if (lua_to_string(prox_lua(), GLOBAL, name + 1, val, len) >= 0) return 0; } set_errf("Variable '%s' not defined!", name); return 1; }
static int lua_to_stream_cfg(struct lua_State *L, enum lua_place from, const char *name, uint32_t socket, struct stream_cfg **stream_cfg, struct hash_set *hs) { int pop; struct stream_cfg *ret; if ((pop = lua_getfrom(L, from, name)) < 0) return -1; if (lua_getfrom(L, TABLE, "actions") < 0) return -1; lua_len(prox_lua(), -1); uint32_t n_actions = lua_tointeger(prox_lua(), -1); lua_pop(prox_lua(), 1); lua_pop(L, 1); size_t mem_size = 0; mem_size += sizeof(*ret); /* one additional action is allocated to allow inserting an additional "default" action to close down TCP sessions from the client side. */ mem_size += sizeof(ret->actions[0]) * (n_actions + 1); ret = prox_zmalloc(sizeof(*ret) + mem_size, socket); ret->n_actions = n_actions; size_t client_contents_len, server_contents_len; char proto[16]; uint32_t timeout_us, timeout_time_wait_us; plogx_dbg("loading stream\n"); if (lua_to_host_set(L, TABLE, "servers", &ret->servers)) return -1; if (lua_to_string(L, TABLE, "l4_proto", proto, sizeof(proto))) return -1; if (lua_to_peer_data(L, TABLE, "client_data", socket, &ret->data[PEER_CLIENT], &client_contents_len, hs)) return -1; if (lua_to_peer_data(L, TABLE, "server_data", socket, &ret->data[PEER_SERVER], &server_contents_len, hs)) return -1; if (lua_to_int(L, TABLE, "timeout", &timeout_us)) { timeout_us = 1000000; } ret->tsc_timeout = usec_to_tsc(timeout_us); double up, dn; if (lua_to_double(L, TABLE, "up_bps", &up)) up = 5000;// Default rate is 40 Mbps if (lua_to_double(L, TABLE, "dn_bps", &dn)) dn = 5000;// Default rate is 40 Mbps const uint64_t hz = rte_get_tsc_hz(); ret->tt_cfg[PEER_CLIENT] = token_time_cfg_create(up, hz, ETHER_MAX_LEN + 20); ret->tt_cfg[PEER_SERVER] = token_time_cfg_create(dn, hz, ETHER_MAX_LEN + 20); if (!strcmp(proto, "tcp")) { ret->proto = IPPROTO_TCP; ret->proc = stream_tcp_proc; ret->is_ended = stream_tcp_is_ended; if (lua_to_int(L, TABLE, "timeout_time_wait", &timeout_time_wait_us)) { timeout_time_wait_us = 2000000; } ret->tsc_timeout_time_wait = usec_to_tsc(timeout_time_wait_us); } else if (!strcmp(proto, "udp")) { plogx_dbg("loading UDP\n"); ret->proto = IPPROTO_UDP; ret->proc = stream_udp_proc; ret->is_ended = stream_udp_is_ended; } else return -1; /* get all actions */ if (lua_getfrom(L, TABLE, "actions") < 0) return -1; uint32_t idx = 0; lua_pushnil(L); while (lua_next(L, -2)) { if (lua_to_peer_action(L, STACK, NULL, &ret->actions[idx], client_contents_len, server_contents_len)) return -1; stream_cfg_verify_action(ret, &ret->actions[idx]); idx++; lua_pop(L, 1); } lua_pop(L, 1); /* For TCP, one of the peers initiates closing down the connection. This is signified by the last action having with zero length. If such an action is not specified in the configuration file, the default is for the client to close the connection. This means that the TCP connection at the client will go into a TIME_WAIT state and the server releases all the resources avoiding resource starvation at the server. */ if (ret->proto == IPPROTO_TCP && ret->actions[ret->n_actions - 1].len != 0) { ret->actions[ret->n_actions].len = 0; ret->actions[ret->n_actions].beg = 0; ret->actions[ret->n_actions].peer = PEER_CLIENT; ret->n_actions++; } if (IPPROTO_TCP == ret->proto) stream_tcp_calc_len(ret, &ret->n_pkts, &ret->n_bytes); else stream_udp_calc_len(ret, &ret->n_pkts, &ret->n_bytes); lua_pop(L, pop); *stream_cfg = ret; return 0; }
static int lua_to_peer_data(struct lua_State *L, enum lua_place from, const char *name, uint32_t socket, struct peer_data *peer_data, size_t *cl, struct hash_set *hs) { uint32_t hdr_len, hdr_beg, content_len, content_beg; char hdr_file[256], content_file[256]; int pop; if ((pop = lua_getfrom(L, from, name)) < 0) return -1; if (!lua_istable(L, -1)) return -1; if (lua_getfrom(L, TABLE, "header") < 0) return -1; if (lua_to_int(L, TABLE, "len", &hdr_len) < 0) return -1; if (lua_to_int(L, TABLE, "beg", &hdr_beg) < 0) return -1; if (lua_to_string(L, TABLE, "file_name", hdr_file, sizeof(hdr_file)) < 0) return -1; lua_pop(L, 1); if (lua_getfrom(L, TABLE, "content") < 0) return -1; if (lua_to_int(L, TABLE, "len", &content_len) < 0) return -1; if (lua_to_int(L, TABLE, "beg", &content_beg) < 0) return -1; if (lua_to_string(L, TABLE, "file_name", content_file, sizeof(content_file)) < 0) return -1; lua_pop(L, 1); if (hdr_len == UINT32_MAX) { long ret = file_get_size(hdr_file); if (ret < 0) { plog_err("%s", file_get_error()); return -1; } hdr_len = ret - hdr_beg; } if (content_len == UINT32_MAX) { long ret = file_get_size(content_file); if (ret < 0) { plog_err("%s", file_get_error()); return -1; } content_len = ret - content_beg; } *cl = content_len; peer_data->hdr_len = hdr_len; if (file_read_cached(hdr_file, &peer_data->hdr, hdr_beg, hdr_len, socket, hs)) return -1; if (file_read_cached(content_file, &peer_data->content, content_beg, content_len, socket, hs)) return -1; lua_pop(L, pop); return 0; }
static int lua_to_stream_cfg(struct lua_State *L, enum lua_place from, const char *name, uint32_t socket, struct stream_cfg **stream_cfg) { int pop; struct stream_cfg *ret; if ((pop = lua_getfrom(L, from, name)) < 0) return -1; if (lua_getfrom(L, TABLE, "actions") < 0) return -1; lua_len(prox_lua(), -1); uint32_t n_actions = lua_tointeger(prox_lua(), -1); lua_pop(prox_lua(), 1); lua_pop(L, 1); size_t mem_size = 0; mem_size += sizeof(*ret); mem_size += sizeof(ret->actions[0])*n_actions; ret = rte_zmalloc_socket(NULL, sizeof(*ret) + mem_size, RTE_CACHE_LINE_SIZE, socket); ret->n_actions = n_actions; size_t client_contents_len, server_contents_len; char proto[16]; uint32_t timeout_us, timeout_time_wait_us; plogx_dbg("loading stream\n"); if (lua_to_host_set(L, TABLE, "servers", &ret->servers) || lua_to_string(L, TABLE, "l4_proto", proto, sizeof(proto)) || lua_to_peer_data(L, TABLE, "client_data", socket, &ret->data[PEER_CLIENT], &client_contents_len) || lua_to_peer_data(L, TABLE, "server_data", socket, &ret->data[PEER_SERVER], &server_contents_len)) { return -1; } if (lua_to_int(L, TABLE, "timeout", &timeout_us)) { timeout_us = 1000000; } ret->tsc_timeout = (uint64_t)timeout_us * rte_get_tsc_hz()/1000000; if (!strcmp(proto, "tcp")) { ret->proto = IPPROTO_TCP; ret->proc = stream_tcp_proc; ret->is_ended = stream_tcp_is_ended; if (lua_to_int(L, TABLE, "timeout_time_wait", &timeout_time_wait_us)) { timeout_time_wait_us = 2000000; } ret->tsc_timeout_time_wait = (uint64_t)timeout_time_wait_us * rte_get_tsc_hz()/1000000; } else if (!strcmp(proto, "udp")) { plogx_dbg("loading UDP\n"); ret->proto = IPPROTO_UDP; ret->proc = stream_udp_proc; ret->is_ended = stream_udp_is_ended; } else return -1; /* get all actions */ if (lua_getfrom(L, TABLE, "actions") < 0) return -1; uint32_t idx = 0; lua_pushnil(L); while (lua_next(L, -2)) { if (lua_to_peer_action(L, STACK, NULL, &ret->actions[idx], client_contents_len, server_contents_len)) return -1; idx++; lua_pop(L, 1); } lua_pop(L, 1); lua_pop(L, pop); *stream_cfg = ret; return 0; }
static int lua_to_peer_data(struct lua_State *L, enum lua_place from, const char *name, uint32_t socket, struct peer_data *peer_data, size_t *cl) { uint32_t hdr_len, hdr_beg, content_len, content_beg; char hdr_file[256], content_file[256]; int pop; if ((pop = lua_getfrom(L, from, name)) < 0) return -1; if (!lua_istable(L, -1)) return -1; if (lua_getfrom(L, TABLE, "header") < 0) return -1; if (lua_to_int(L, TABLE, "len", &hdr_len) < 0) return -1; if (lua_to_int(L, TABLE, "beg", &hdr_beg) < 0) return -1; if (lua_to_string(L, TABLE, "file_name", hdr_file, sizeof(hdr_file)) < 0) return -1; lua_pop(L, 1); if (lua_getfrom(L, TABLE, "content") < 0) return -1; if (lua_to_int(L, TABLE, "len", &content_len) < 0) return -1; if (lua_to_int(L, TABLE, "beg", &content_beg) < 0) return -1; if (lua_to_string(L, TABLE, "file_name", content_file, sizeof(content_file)) < 0) return -1; lua_pop(L, 1); if (hdr_len == (uint32_t)-1) { char file_name[PATH_MAX]; snprintf(file_name, sizeof(file_name), "%s/%s", get_cfg_dir(), hdr_file); FILE *f = fopen(file_name, "r"); long file_beg; if (!f) return -1; fseek(f, hdr_beg, SEEK_SET); file_beg = ftell(f); fseek(f, 0, SEEK_END); hdr_len = ftell(f) - file_beg; fclose(f); } if (content_len == (uint32_t)-1) { char file_name[PATH_MAX]; snprintf(file_name, sizeof(file_name), "%s/%s", get_cfg_dir(), content_file); FILE *f = fopen(file_name, "r"); long file_beg; if (!f) return -1; fseek(f, content_beg, SEEK_SET); file_beg = ftell(f); fseek(f, 0, SEEK_END); content_len = ftell(f) - file_beg; fclose(f); } *cl = content_len; peer_data->mem = rte_zmalloc_socket(NULL, hdr_len + content_len, RTE_CACHE_LINE_SIZE, socket); PROX_PANIC(peer_data->mem == NULL, "Failed to allocate memory (%u bytes) to hold headers and contents for peer\n", hdr_len + content_len); peer_data->hdr = peer_data->mem; peer_data->hdr_len = hdr_len; peer_data->content = peer_data->mem + hdr_len; char file_name[PATH_MAX]; snprintf(file_name, sizeof(file_name), "%s/%s", get_cfg_dir(), hdr_file); FILE *f = fopen(file_name, "r"); if (!f) { return -1; } fseek(f, hdr_beg, SEEK_SET); size_t ret; ret = fread(peer_data->hdr, 1, hdr_len, f); if ((uint32_t)ret != hdr_len) { plog_err("Failed to read hdr, %zu, %u\n", ret, hdr_len); return -1; } fclose(f); snprintf(file_name, sizeof(file_name), "%s/%s", get_cfg_dir(), content_file); f = fopen(file_name, "r"); if (!f) return -1; fseek(f, content_beg, SEEK_SET); ret = fread(peer_data->content, 1, content_len, f); if ((uint32_t)ret != content_len) { plog_err("Failed to read content, %zu, %u\n", ret, content_len); return -1; } fclose(f); lua_pop(L, pop); return 0; }