diff --git a/sql/prepared_statements.sql b/sql/prepared_statements.sql index caec01e4e4e9f9a2cfa8b7eab7cc9c0101fd1c10..bf14b59146948b04fec2d54c34076db43a7aab6d 100644 --- a/sql/prepared_statements.sql +++ b/sql/prepared_statements.sql @@ -1,3 +1,6 @@ +-- check switch +select count(*) from switch where switch_id = :switch_id; + -- ip_conflict select ip_conflict::int from mueb where mac_address = :mac; diff --git a/src/callouts.cc b/src/callouts.cc index 5e841675394457629919e5a453e7c2eb774716ac..aae944de8f032a9bc57c04e63e6b632c850ab299 100644 --- a/src/callouts.cc +++ b/src/callouts.cc @@ -13,7 +13,7 @@ #include "globals.h" #include "logger.h" -static std::tuple<int, std::string, std::string, std::string> parseOption82( +static std::tuple<int, std::string, std::string> parseOption82( const isc::dhcp::Pkt4Ptr& query4_ptr) { /* Get switch hostname and port name from DHCP option 82 * Also check if option 82 is valid @@ -24,7 +24,7 @@ static std::tuple<int, std::string, std::string, std::string> parseOption82( !option82->getOption(1)->valid() || !option82->getOption(2) || !option82->getOption(2)->valid()) { LOG_FATAL(kea_hook_logger, KEA_HOOK_DHCP_OPTION_82_ERROR); - return std::make_tuple(1, nullptr, nullptr, nullptr); + return std::make_tuple(1, nullptr, nullptr); } const auto& circuit_id{option82->getOption(1)->getData()}; @@ -33,20 +33,24 @@ static std::tuple<int, std::string, std::string, std::string> parseOption82( // Check suboption ID types if (circuit_id[0] != 0 || remote_id[0] != 1) { LOG_FATAL(kea_hook_logger, KEA_HOOK_DHCP_OPTION_82_ERROR); - return std::make_tuple(1, nullptr, nullptr, nullptr); + return std::make_tuple(1, nullptr, nullptr); } const auto& port_id{std::to_string(circuit_id[4]) + "/" + std::to_string(circuit_id[5])}; - std::string switch_name{remote_id.begin() + 2, remote_id.end()}; + std::string switch_id{remote_id.begin() + 2, remote_id.end()}; - try { - const auto& switch_id{g_switch_data.at(switch_name)}; - return std::make_tuple(0, std::move(switch_name), port_id, switch_id); - } catch (const std::out_of_range& e) { + // Check if switch exists + const char* values[1] = {switch_id.c_str()}; + isc::db::PgSqlResult r(PQexecPrepared(*g_pg_sql_connection, "check_switch", 1, + values, nullptr, nullptr, 0)); + + if (r.getRows() <= 0 || std::stoi(PQgetvalue(r, 0, 0)) <= 0) { LOG_FATAL(kea_hook_logger, KEA_HOOK_DHCP_OPTION_82_ERROR); - return std::make_tuple(1, nullptr, nullptr, nullptr); + return std::make_tuple(1, nullptr, nullptr); } + + return std::make_tuple(0, std::move(switch_id), port_id); } extern "C" { @@ -63,8 +67,7 @@ int pkt4_receive(isc::hooks::CalloutHandle& handle) { return 0; } - const auto& [result, switch_name, port_id, switch_id] = - parseOption82(query4_ptr); + const auto& [result, switch_id, port_id] = parseOption82(query4_ptr); if (result != 0) { return 1; } @@ -78,7 +81,7 @@ int pkt4_receive(isc::hooks::CalloutHandle& handle) { if (r.getRows() <= 0) { LOG_ERROR(kea_hook_logger, KEA_HOOK_UNKNOWN_ROOM) .arg(mac_address) - .arg(switch_name) + .arg(switch_id) .arg(port_id); return 1; } @@ -147,7 +150,7 @@ int lease4_select(isc::hooks::CalloutHandle& handle) { try { isc::db::PgSqlTransaction transaction(*g_pg_sql_connection); - auto [result, switch_name, port_id, switch_id] = parseOption82(query4_ptr); + auto [result, switch_id, port_id] = parseOption82(query4_ptr); if (result != 0) { return 1; } @@ -174,7 +177,7 @@ int lease4_select(isc::hooks::CalloutHandle& handle) { if (r2.getRows() <= 0) { LOG_ERROR(kea_hook_logger, KEA_HOOK_UNKNOWN_ROOM) .arg(mac_address) - .arg(switch_name) + .arg(switch_id) .arg(port_id); return 1; diff --git a/src/framework_functions.cc b/src/framework_functions.cc index 2e74f6b04a277284cd1817233d77b28e1a30cd7d..6ff904527b3cdc499293f031a3a829413ba19c76 100644 --- a/src/framework_functions.cc +++ b/src/framework_functions.cc @@ -6,7 +6,6 @@ #include "globals.h" #include "logger.h" -std::map<std::string, std::string> g_switch_data; isc::db::PgSqlConnection* g_pg_sql_connection; extern "C" { @@ -38,9 +37,13 @@ int load(isc::hooks::LibraryHandle& handle) { g_pg_sql_connection->openDatabase(); // Store prepared statements - std::array<isc::db::PgSqlTaggedStatement, 8> statements{ - {{2, - {isc::db::OID_TEXT, 869}, + std::array<isc::db::PgSqlTaggedStatement, 9> statements{ + {{1, + {isc::db::OID_TEXT}, + "check_switch", + "select count(*) from switch where switch_id = $1"}, + {2, + {isc::db::OID_TEXT, isc::db::OID_TEXT}, "mueb_in_room", "select room_id from port p join room r using(room_id) where " "p.port_id " @@ -61,18 +64,18 @@ int load(isc::hooks::LibraryHandle& handle) { "ip_override " "is not null"}, {2, - {isc::db::OID_TEXT, 869}, + {isc::db::OID_TEXT, isc::db::OID_TEXT}, "ip_address", "select ip_address from port p join room r using(room_id) where " "p.port_id " "= $1 and switch_id = $2"}, {2, - {isc::db::OID_TEXT, 869}, + {isc::db::OID_TEXT, isc::db::OID_TEXT}, "clear_port", "update mueb set port_id = null, switch_id = null where port_id = $1 " "and switch_id = $2"}, {3, - {829, isc::db::OID_TEXT, 869}, + {829, isc::db::OID_TEXT, isc::db::OID_TEXT}, "insert_or_update_mueb", "insert into mueb (mac_address) values ($1) on conflict " "(mac_address) do update set " @@ -90,20 +93,6 @@ int load(isc::hooks::LibraryHandle& handle) { return 1; } - // Cache switch data - isc::db::PgSqlResult r( - PQexec(*g_pg_sql_connection, "select hostname, switch_id from switch")); - if (r.getRows() <= 0) { - LOG_FATAL(kea_hook_logger, KEA_HOOK_DATABASE_FAILED) - .arg("Switch table is empty!"); - - return 1; - } - - for (int i = 0; i < r.getRows(); ++i) { - g_switch_data.emplace(PQgetvalue(r, i, 0), PQgetvalue(r, i, 1)); - } - LOG_DEBUG(kea_hook_logger, 0, KEA_HOOK_OPEN_DATABASE); return 0; diff --git a/src/globals.h b/src/globals.h index 813c23c0b72d39ee3b1e626b39f987732d8f64b5..070f70c609b257aae441d6adaeaec1410b11ec1c 100644 --- a/src/globals.h +++ b/src/globals.h @@ -6,7 +6,6 @@ #include <map> #include <string> -extern std::map<std::string, std::string> g_switch_data; extern isc::db::PgSqlConnection* g_pg_sql_connection; -#endif // KEA_HOOK_SRC_GLOBALS_H_ \ No newline at end of file +#endif // KEA_HOOK_SRC_GLOBALS_H_ \ No newline at end of file