Skip to content

Commit

Permalink
Merge pull request #3239 from sysown/v2.1.0-3238
Browse files Browse the repository at this point in the history
Closes #3238: Improve error handling when port is already in use when instantiating 'ProxySQL_RestAPI_Server'
  • Loading branch information
JavierJF authored Jan 11, 2021
2 parents 718298f + 5dbddb3 commit 17a4b4a
Showing 1 changed file with 62 additions and 2 deletions.
64 changes: 62 additions & 2 deletions lib/ProxySQL_Admin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5708,6 +5708,51 @@ std::shared_ptr<httpserver::http_response> make_response(
return response;
}

/**
* @brief Checks if the supplied port is available.
*
* @param port_num The port number to check.
* @param free Output parameter. True if the port is free, false otherwise.
*
* @return Returns:
* - '-1' in case 'SO_REUSEADDR' fails to be set for the check.
* - '-2' in case of invalid arguments supplied.
* - '0' otherwise.
*/
int check_port_availability(int port_num, bool* port_free) {
int ecode = 0;
int sfd = 0;
int reuseaddr = 1;
struct sockaddr_in tmp_addr;

if (port_num == 0 || port_free == nullptr) {
return -2;
}

// set 'port_free' to false by default
*port_free = false;

sfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&tmp_addr, 0, sizeof(tmp_addr));
tmp_addr.sin_family = AF_INET;
tmp_addr.sin_port = htons(port_num);
tmp_addr.sin_addr.s_addr = INADDR_ANY;

if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr, sizeof(reuseaddr)) == -1) {
close(sfd);
ecode = -1;
} else {
if (bind(sfd, (struct sockaddr*)&tmp_addr, sizeof(tmp_addr)) == -1) {
close(sfd);
} else {
*port_free = true;
close(sfd);
}
}

return ecode;
}

void ProxySQL_Admin::flush_admin_variables___database_to_runtime(SQLite3DB *db, bool replace) {
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Flushing ADMIN variables. Replace:%d\n", replace);
char *error=NULL;
Expand Down Expand Up @@ -5788,8 +5833,23 @@ void ProxySQL_Admin::flush_admin_variables___database_to_runtime(SQLite3DB *db,
return http_response;
}
};

bool free_restapi_port = false;
int e_port_check = check_port_availability(variables.restapi_port, &free_restapi_port);

if (free_restapi_port == false) {
if (e_port_check == -1) {
proxy_error("Unable to start 'ProxySQL_RestAPI_Server', failed to set 'SO_REUSEADDR' to check port availability.\n");
} else {
proxy_error(
"Unable to start 'ProxySQL_RestAPI_Server', port '%d' already in use.\n",
variables.restapi_port
);
}
}

if (variables.restapi_enabled != variables.restapi_enabled_old) {
if (variables.restapi_enabled) {
if (variables.restapi_enabled && free_restapi_port) {
AdminRestApiServer = new ProxySQL_RESTAPI_Server(
variables.restapi_port, {{"/metrics", prometheus_callback}}
);
Expand All @@ -5804,7 +5864,7 @@ void ProxySQL_Admin::flush_admin_variables___database_to_runtime(SQLite3DB *db,
delete AdminRestApiServer;
AdminRestApiServer = NULL;
}
if (variables.restapi_enabled) {
if (variables.restapi_enabled && free_restapi_port) {
AdminRestApiServer = new ProxySQL_RESTAPI_Server(
variables.restapi_port, {{"/metrics", prometheus_callback}}
);
Expand Down

0 comments on commit 17a4b4a

Please sign in to comment.