Commit 7eb0ba8c authored by kharade's avatar kharade

http2 server added

parent 54a49ba2
......@@ -20,6 +20,7 @@ AUSF =
SUPPORT_FEATURES:{
# STRING, {"yes", "no"},
USE_FQDN_DNS = "@USE_FQDN_DNS@"; # Set to yes if AUSF will relying on a DNS to resolve UDM's FQDN
USE_HTTP2 = "@USE_HTTP2@"; # Set to yes to enable HTTP2 for AMF server
}
# UDM Information
......
......@@ -7,6 +7,7 @@ SBI_PORT=${SBI_PORT:-80}
UDM_PORT=${UDM_PORT:-80}
SBI_HTTP2_PORT=${SBI_HTTP2_PORT:-8080}
SBI_API_VERSION=${SBI_API_VERSION:-v1}
USE_HTTP2=${USE_HTTP2:-no}
if [[ ${USE_FQDN_DNS} == "yes" ]];then
UDM_IP_ADDRESS=${UDM_IP_ADDRESS:-0.0.0.0}
......
......@@ -34,6 +34,7 @@ include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
file(GLOB AUSF_API_SERVER_src_files
${AUSF_API_SERVER_DIR}/ausf-api-server.cpp
${AUSF_API_SERVER_DIR}/ausf_http2-server.cpp
${AUSF_API_SERVER_DIR}/model/*.cpp
${AUSF_API_SERVER_DIR}/api/*.cpp
${AUSF_API_SERVER_DIR}/impl/*.cpp
......
......@@ -189,7 +189,7 @@ void DefaultApi::ue_authentications_deregister_post_handler(
}
}
void DefaultApi::ue_authentications_post_handler(
void DefaultApi:: ue_authentications_post_handler(
const Pistache::Rest::Request& request,
Pistache::Http::ResponseWriter response) {
Logger::ausf_server().info("Received ue_authentications_post Request");
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file ausf_http2-server.h
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2021
\email: tien-thinh.nguyen@eurecom.fr
*/
#ifndef FILE_AUSF_HTTP2_SERVER_SEEN
#define FILE_AUSF_HTTP2_SERVER_SEEN
#include "conversions.hpp"
#include "ausf_app.hpp"
#include <nghttp2/asio_http2_server.h>
#include "ConfirmationData.h"
#include "AuthenticationInfo.h"
#include "DeregistrationInfo.h"
#include "EapSession.h"
#include "RgAuthenticationInfo.h"
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;
// using namespace oai::ausf_server::model;
using namespace oai::ausf::app;
class ausf_http2_server {
public:
ausf_http2_server(std::string addr, uint32_t port, ausf_app* ausf_app_inst)
: m_address(addr), m_port(port), server(), m_ausf_app(ausf_app_inst) {}
void start();
void init(size_t thr) {}
void eap_auth_method_handler(
const std::string& authCtxId, const EapSession& eapSession,
const response& response);
void rg_authentications_post_handler(
const RgAuthenticationInfo& rgAuthenticationInfo,
const response& response);
void ue_authentications_auth_ctx_id5g_aka_confirmation_put_handler(
const std::string& authCtxId, const ConfirmationData& confirmationData,
const response& response);
void ue_authentications_deregister_post_handler(
const DeregistrationInfo& deregistrationInfo, const response& response);
void ue_authentications_post_handler(
const AuthenticationInfo& authenticationInfo, const response& response);
void stop();
private:
std::string m_address;
uint32_t m_port;
http2 server;
ausf_app* m_ausf_app;
};
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file ausf_http2-server.cpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2020
\email: tien-thinh.nguyen@eurecom.fr
*/
#include "ausf-http2-server.h"
#include <boost/algorithm/string.hpp>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <regex>
#include <nlohmann/json.hpp>
#include <string>
#include "string.hpp"
#include "logger.hpp"
#include "ausf_config.hpp"
#include "3gpp_29.500.h"
#include "mime_parser.hpp"
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;
using namespace oai::ausf_server::model;
using namespace config;
extern ausf_config ausf_cfg;
//------------------------------------------------------------------------------
void ausf_http2_server::start() {
boost::system::error_code ec;
Logger::ausf_server().info("HTTP2 server started");
// Default API
server.handle(
NAUSF_AUTH_BASE + ausf_cfg.sbi_api_version + NAUSF_UE_AUTHS,
[&](const request& request, const response& response) {
request.on_data([&](const uint8_t* data, std::size_t len) {
std::string msg((char*) data, len);
try {
std::vector<std::string> split_result;
boost::split(
split_result, request.uri().path, boost::is_any_of("/"));
if (request.method().compare("POST") == 0 && len > 0) {
AuthenticationInfo authenticationInfo;
nlohmann::json::parse(msg.c_str()).get_to(authenticationInfo);
this->ue_authentications_post_handler(
authenticationInfo, response);
}
} catch (std::exception& e) {
Logger::ausf_server().warn(
"Invalid request (error: %s)!", e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
}
});
});
server.handle(
NAUSF_AUTH_BASE + ausf_cfg.sbi_api_version + NAUSF_UE_AUTHS + "/",
[&](const request& request, const response& response) {
request.on_data([&](const uint8_t* data, std::size_t len) {
std::string msg((char*) data, len);
try {
std::vector<std::string> split_result;
boost::split(
split_result, request.uri().path, boost::is_any_of("/"));
if (request.method().compare("POST") == 0 && len > 0) {
if (split_result[split_result.size() - 1].compare(
"eap-session") == 0) {
EapSession eapSession;
std::string authCtxId =
split_result[split_result.size() - 2].c_str();
nlohmann::json::parse(msg.c_str()).get_to(eapSession);
this->eap_auth_method_handler(authCtxId, eapSession, response);
}
if (split_result[split_result.size() - 1].compare("deregister") ==
0) {
DeregistrationInfo deregistrationInfo;
nlohmann::json::parse(msg.c_str()).get_to(deregistrationInfo);
this->ue_authentications_deregister_post_handler(
deregistrationInfo, response);
}
}
if (request.method().compare("PUT") == 0 && len > 0) {
ConfirmationData confirmationData;
std::string authCtxId =
split_result[split_result.size() - 2].c_str();
nlohmann::json::parse(msg.c_str()).get_to(confirmationData);
this->ue_authentications_auth_ctx_id5g_aka_confirmation_put_handler(
authCtxId, confirmationData, response);
}
} catch (std::exception& e) {
Logger::ausf_server().warn(
"Invalid request (error: %s)!", e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
}
});
});
server.handle(
NAUSF_AUTH_BASE + ausf_cfg.sbi_api_version + NAUSF_RG_AUTH,
[&](const request& request, const response& response) {
request.on_data([&](const uint8_t* data, std::size_t len) {
std::string msg((char*) data, len);
try {
std::vector<std::string> split_result;
boost::split(
split_result, request.uri().path, boost::is_any_of("/"));
if (request.method().compare("POST") == 0 && len > 0) {
RgAuthenticationInfo rgAuthenticationInfo;
std::string authCtxId =
split_result[split_result.size() - 2].c_str();
nlohmann::json::parse(msg.c_str()).get_to(rgAuthenticationInfo);
this->rg_authentications_post_handler(
rgAuthenticationInfo, response);
}
} catch (std::exception& e) {
Logger::ausf_server().warn(
"Invalid request (error: %s)!", e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
}
});
});
if (server.listen_and_serve(ec, m_address, std::to_string(m_port))) {
std::cerr << "HTTP Server error: " << ec.message() << std::endl;
}
}
//------------------------------------------------------------------------
void ausf_http2_server::eap_auth_method_handler(
const std::string& authCtxId, const EapSession& eapSession,
const response& response) {
Logger::ausf_server().info("eap_auth_method");
header_map h;
response.write_head(HTTP_STATUS_CODE_501_NOT_IMPLEMENTED, h);
response.end("eap_auth_method API has not been implemented yet!");
}
//------------------------------------------------------------------------
void ausf_http2_server::rg_authentications_post_handler(
const RgAuthenticationInfo& rgAuthenticationInfo,
const response& response) {
Logger::ausf_server().info("rg_authentications_post");
header_map h;
response.write_head(HTTP_STATUS_CODE_501_NOT_IMPLEMENTED, h);
response.end("rg_authentications_post API has not been implemented yet!");
}
//------------------------------------------------------------------------
void ausf_http2_server::ue_authentications_deregister_post_handler(
const DeregistrationInfo& deregistrationInfo, const response& response) {
Logger::ausf_server().info("ue_authentications_deregister_post");
header_map h;
response.write_head(HTTP_STATUS_CODE_501_NOT_IMPLEMENTED, h);
response.end(
"ue_authentications_deregister_post API has not been implemented yet!");
}
//------------------------------------------------------------------------
void ausf_http2_server::
ue_authentications_auth_ctx_id5g_aka_confirmation_put_handler(
const std::string& authCtxId, const ConfirmationData& confirmationData,
const response& response) {
Logger::ausf_server().info("Received 5g_aka_confirmation Request");
Logger::ausf_server().info(
"5gaka confirmation received with authctxID %s", authCtxId.c_str());
nlohmann::json json_data = {};
Pistache::Http::Code code = {};
header_map h;
m_ausf_app->handle_ue_authentications_confirmation(
authCtxId, confirmationData, json_data, code);
// ausf --> seaf
Logger::ausf_server().debug(
"5g-aka-confirmation response:\n %s", json_data.dump().c_str());
Logger::ausf_server().info(
"Send 5g-aka-confirmation response to SEAF (Code %d)", code);
if (code == Pistache::Http::Code::Ok)
response.write_head(HTTP_STATUS_CODE_200_OK, h);
else
response.write_head(HTTP_STATUS_CODE_403_FORBIDDEN, h);
response.end(json_data.dump().c_str());
}
//------------------------------------------------------------------------
void ausf_http2_server::ue_authentications_post_handler(
const AuthenticationInfo& authenticationInfo, const response& response) {
Logger::ausf_server().info("Received ue_authentications_post Request");
std::string reponse_from_udm = {};
std::string location = {};
UEAuthenticationCtx ue_auth_ctx = {};
nlohmann::json UEAuthCtx_json = {};
Pistache::Http::Code code = {};
header_map h;
m_ausf_app->handle_ue_authentications(
authenticationInfo, UEAuthCtx_json, location, code);
Logger::ausf_server().debug(
"Auth response:\n %s", UEAuthCtx_json.dump().c_str());
Logger::ausf_server().info("Send Auth response to SEAF (Code %d)", code);
if (code == Pistache::Http::Code::Created)
response.write_head(HTTP_STATUS_CODE_201_CREATED, h);
else
response.write_head(HTTP_STATUS_CODE_404_NOT_FOUND, h);
response.end(UEAuthCtx_json.dump().c_str());
}
//------------------------------------------------------------------------
\ No newline at end of file
......@@ -78,6 +78,9 @@ void ausf_client::curl_http_client(
curl_global_init(CURL_GLOBAL_ALL);
CURL* curl = curl_easy_init();
uint8_t http_version = 1;
if (ausf_cfg.use_http2) http_version = 2;
if (curl) {
CURLcode res = {};
struct curl_slist* headers = nullptr;
......@@ -103,6 +106,15 @@ void ausf_client::curl_http_client(
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1);
curl_easy_setopt(curl, CURLOPT_INTERFACE, ausf_cfg.sbi.if_name.c_str());
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(
curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information.
long httpCode = {0};
......
......@@ -62,6 +62,7 @@ ausf_config::ausf_config() : sbi(), ausf_name(), pid_dir(), instance() {
udm_addr.api_version = "v1";
udm_addr.fqdn = {};
use_fqdn_dns = false;
use_http2 = false;
}
//------------------------------------------------------------------------------
......@@ -155,6 +156,14 @@ int ausf_config::load(const std::string& config_file) {
use_fqdn_dns = false;
}
support_features.lookupValue(
AUSF_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2, opt);
if (boost::iequals(opt, "yes")) {
use_http2 = true;
} else {
use_http2 = false;
}
} catch (const SettingNotFoundException& nfex) {
Logger::ausf_app().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath());
......@@ -240,6 +249,13 @@ void ausf_config::display() {
Logger::config().info(" HTTP2 Port............: %d", sbi_http2_port);
Logger::config().info(
" API Version...........: %s", sbi_api_version.c_str());
Logger::config().info("- Supported Features:");
Logger::config().info(
" Use FQDN ..............: %s",
use_fqdn_dns ? "Yes" : "No");
Logger::config().info(
" Use HTTP2..............: %s",
use_http2 ? "Yes" : "No");
Logger::config().info("- UDM:");
Logger::config().info(
......
......@@ -63,6 +63,7 @@
#define AUSF_CONFIG_STRING_SUPPORT_FEATURES "SUPPORT_FEATURES"
#define AUSF_CONFIG_STRING_SUPPORT_FEATURES_USE_FQDN_DNS "USE_FQDN_DNS"
#define AUSF_CONFIG_STRING_SUPPORT_FEATURES_USE_HTTP2 "USE_HTTP2"
#define AUSF_CONFIG_STRING_FQDN_DNS "FQDN"
using namespace libconfig;
......@@ -102,6 +103,7 @@ class ausf_config {
} udm_addr;
bool use_fqdn_dns;
bool use_http2;
};
} // namespace config
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
*file except in compliance with the License. You may obtain a copy of the
*License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef FILE_3GPP_29_500_SEEN
#define FILE_3GPP_29_500_SEEN
enum http_status_code_e {
HTTP_STATUS_CODE_100_CONTINUE = 100,
HTTP_STATUS_CODE_200_OK = 200,
HTTP_STATUS_CODE_201_CREATED = 201,
HTTP_STATUS_CODE_202_ACCEPTED = 202,
HTTP_STATUS_CODE_204_NO_CONTENT = 204,
HTTP_STATUS_CODE_300_MULTIPLE_CHOICES = 300,
HTTP_STATUS_CODE_303_SEE_OTHER = 303,
HTTP_STATUS_CODE_307_TEMPORARY_REDIRECT = 307,
HTTP_STATUS_CODE_308_PERMANENT_REDIRECT = 308,
HTTP_STATUS_CODE_400_BAD_REQUEST = 400,
HTTP_STATUS_CODE_401_UNAUTHORIZED = 401,
HTTP_STATUS_CODE_403_FORBIDDEN = 403,
HTTP_STATUS_CODE_404_NOT_FOUND = 404,
HTTP_STATUS_CODE_405_METHOD_NOT_ALLOWED = 405,
HTTP_STATUS_CODE_406_NOT_ACCEPTABLE = 406,
HTTP_STATUS_CODE_408_REQUEST_TIMEOUT = 408,
HTTP_STATUS_CODE_409_CONFLICT = 409,
HTTP_STATUS_CODE_410_GONE = 410,
HTTP_STATUS_CODE_411_LENGTH_REQUIRED = 411,
HTTP_STATUS_CODE_412_PRECONDITION_FAILED = 412,
HTTP_STATUS_CODE_413_PAYLOAD_TOO_LARGE = 413,
HTTP_STATUS_CODE_414_URI_TOO_LONG = 414,
HTTP_STATUS_CODE_415_UNSUPPORTED_MEDIA_TYPE_NA = 415,
HTTP_STATUS_CODE_429_TOO_MANY_REQUESTS = 429,
HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR = 500,
HTTP_STATUS_CODE_501_NOT_IMPLEMENTED = 501,
HTTP_STATUS_CODE_503_SERVICE_UNAVAILABLE = 503,
HTTP_STATUS_CODE_504_GATEWAY_TIMEOUT = 504
};
enum protocol_application_error_e {
INVALID_API = 0, // 400 Bad Request
INVALID_MSG_FORMAT = 1, // 400 Bad Request
INVALID_QUERY_PARAM = 2, // 400 Bad Request
MANDATORY_QUERY_PARAM_INCORRECT = 3, // 400 Bad Request
OPTIONAL_QUERY_PARAM_INCORRECT = 4, // 400 Bad Request
MANDATORY_QUERY_PARAM_MISSING = 5, // 400 Bad Request
MANDATORY_IE_INCORRECT = 6, // 400 Bad Request
OPTIONAL_IE_INCORRECT = 7, // 400 Bad Request
MANDATORY_IE_MISSING = 8, // 400 Bad Request
UNSPECIFIED_MSG_FAILURE = 9, // 400 Bad Request
MODIFICATION_NOT_ALLOWED = 10, // 403 Forbidden
SUBSCRIPTION_NOT_FOUND = 11, // 404 Not Found
RESOURCE_URI_STRUCTURE_NOT_FOUND = 12, // 404 Not Found
INCORRECT_LENGTH = 13, // 411 Length Required
NF_CONGESTION_RISK = 14, // 429 Too Many Requests
INSUFFICIENT_RESOURCES = 15, // 500 Internal Server Error
UNSPECIFIED_NF_FAILURE = 16, // 500 Internal Server Error
SYSTEM_FAILURE = 17, // 500 Internal Server Error
NF_CONGESTION = 18, // 503 Service Unavailable
};
static const std::vector<std::string> protocol_application_error_e2str{
"INVALID_API",
"INVALID_MSG_FORMAT",
"INVALID_QUERY_PARAM",
"MANDATORY_QUERY_PARAM_INCORRECT",
"OPTIONAL_QUERY_PARAM_INCORRECT",
"MANDATORY_QUERY_PARAM_MISSING",
"MANDATORY_IE_INCORRECT",
"OPTIONAL_IE_INCORRECT",
"MANDATORY_IE_MISSING",
"UNSPECIFIED_MSG_FAILURE",
"MODIFICATION_NOT_ALLOWED",
"SUBSCRIPTION_NOT_FOUND",
"RESOURCE_URI_STRUCTURE_NOT_FOUND",
"INCORRECT_LENGTH ",
"NF_CONGESTION_RISK",
"INSUFFICIENT_RESOURCES",
"UNSPECIFIED_NF_FAILURE",
"SYSTEM_FAILURE",
"NF_CONGESTION"};
#endif // FILE_3GPP_29_500_SEEN
......@@ -108,4 +108,9 @@ enum http_response_codes_e {
HTTP_RESPONSE_CODE_GATEWAY_TIMEOUT = 504
};
#define NAUSF_AUTH_BASE "/nausf-auth/"
#define NAUSF_UE_AUTHS "/ue-authentications"
#define NAUSF_UE_AUTHS_DEREG "/ue-authentications/deregister"
#define NAUSF_RG_AUTH "/rg-authentications"
#endif
......@@ -16,6 +16,7 @@
#include "logger.hpp"
#include "ausf-api-server.h"
#include "ausf-http2-server.h"
#include "ausf_config.hpp"
#include "ausf_app.hpp"
#include "options.hpp"
......@@ -39,9 +40,9 @@ using namespace std;
using namespace config;
ausf_config ausf_cfg;
ausf_app* ausf_app_inst = nullptr;
AUSFApiServer* api_server = nullptr;
#include "ausf_config.hpp"
ausf_app* ausf_app_inst = nullptr;
AUSFApiServer* api_server = nullptr;
ausf_http2_server* ausf_api_server_2 = nullptr;
//------------------------------------------------------------------------------
void my_app_signal_handler(int s) {
......@@ -109,7 +110,15 @@ int main(int argc, char** argv) {
api_server = new AUSFApiServer(addr, ausf_app_inst);
api_server->init(2);
std::thread ausf_manager(&AUSFApiServer::start, api_server);
// AUSF NGHTTP API server (HTTP2)
ausf_api_server_2 = new ausf_http2_server(
conv::toString(ausf_cfg.sbi.addr4), ausf_cfg.sbi_http2_port,
ausf_app_inst);
std::thread ausf_http2_manager(&ausf_http2_server::start, ausf_api_server_2);
ausf_manager.join();
ausf_http2_manager.join();
FILE* fp = NULL;
std::string filename = fmt::format("/tmp/ausf_{}.status", getpid());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment