Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ARG DEBIAN_VERSION=11.5-slim
ARG POCO_VERSION=poco-tip-v2
ARG DEBIAN_VERSION=bookworm
ARG POCO_VERSION=poco-tip-v4-tag
ARG CPPKAFKA_VERSION=tip-v1
ARG VALIJASON_VERSION=tip-v1.0.2
ARG APP_NAME=owgw
Expand Down Expand Up @@ -100,7 +100,7 @@ RUN mkdir -p $APP_ROOT $APP_CONFIG && \

RUN apt-get update && apt-get install --no-install-recommends -y \
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
libmariadb-dev-compat libpq5 unixodbc postgresql-client libfmt7 sqlite3
libmariadb-dev-compat libpq5 unixodbc postgresql-client libfmt9 sqlite3

COPY readiness_check /readiness_check
COPY test_scripts/curl/cli /cli
Expand Down
2 changes: 2 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
FILEUPLOADER_HOST_KEY_PASSWORD=${FILEUPLOADER_HOST_KEY_PASSWORD:-"mypassword"} \
FILEUPLOADER_PATH=${FILEUPLOADER_PATH:-"\${APP_ROOT}/uploads"} \
FILEUPLOADER_URI=${FILEUPLOADER_URI:-"https://localhost:16003"} \
FILEUPLOADER_MAXSIZE=${FILEUPLOADER_MAXSIZE:-"10000"} \
SERVICE_KEY=${SERVICE_KEY:-"\${APP_ROOT}/certs/restapi-key.pem"} \
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
SYSTEM_DATA=${SYSTEM_DATA:-"\${APP_ROOT}/data"} \
Expand Down Expand Up @@ -76,6 +77,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
CERTIFICATES_ALLOWMISMATCH=${CERTIFICATES_ALLOWMISMATCH:-"false"} \
IPINFO_DEFAULT_COUNTRY=${IPINFO_DEFAULT_COUNTRY:-"US"} \
DEVICE_SESSION_TIMEOUT=${DEVICE_SESSION_TIMEOUT:-"600"} \
LOGGING_LEVEL=${LOGGING_LEVEL:-"information"} \
envsubst < /"${APP_NAME}".properties.tmpl > "${APP_CONFIG}"/"${APP_NAME}".properties
fi

Expand Down
5 changes: 3 additions & 2 deletions owgw.properties.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ openwifi.fileuploader.host.0.cert = ${FILEUPLOADER_HOST_CERT}
openwifi.fileuploader.host.0.key = ${FILEUPLOADER_HOST_KEY}
openwifi.fileuploader.host.0.key.password = ${FILEUPLOADER_HOST_KEY_PASSWORD}
openwifi.fileuploader.path = ${FILEUPLOADER_PATH}
openwifi.fileuploader.maxsize = 10000
# maxsize in KB
openwifi.fileuploader.maxsize = ${FILEUPLOADER_MAXSIZE}
openwifi.fileuploader.uri = ${FILEUPLOADER_URI}

#
Expand Down Expand Up @@ -182,4 +183,4 @@ archiver.db.3.keep = 7
########################################################################
logging.type = console
logging.path = $OWGW_ROOT/logs
logging.level = information
logging.level = ${LOGGING_LEVEL}
166 changes: 109 additions & 57 deletions src/AP_WS_Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <Poco/Net/Context.h>
#include <Poco/Net/HTTPServerRequestImpl.h>
#include <Poco/Net/HTTPServerResponseImpl.h>
#include <Poco/JSON/JSONException.h>
#include <Poco/Net/NetException.h>
#include <Poco/Net/SSLException.h>
#include <Poco/Net/SecureStreamSocketImpl.h>
Expand Down Expand Up @@ -39,7 +40,7 @@ namespace OpenWifi {
Poco::Net::HTTPServerResponse &response,
uint64_t session_id, Poco::Logger &L,
std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> R)
: Logger_(L) {
: Logger_(L), IncomingFrame_(0) {

Reactor_ = R.first;
DbSession_ = R.second;
Expand All @@ -54,6 +55,7 @@ namespace OpenWifi {
WS_->setNoDelay(false);
WS_->setKeepAlive(true);
WS_->setBlocking(false);
IncomingFrame_.resize(0);
uuid_ = MicroServiceRandom(std::numeric_limits<std::uint64_t>::max()-1);

AP_WS_Server()->IncrementConnectionCount();
Expand Down Expand Up @@ -600,36 +602,95 @@ namespace OpenWifi {
EndConnection();
}

void AP_WS_Connection::ProcessWSFinalPayload() {
auto IncomingSize = IncomingFrame_.size();

if (IncomingSize == 0) {
poco_warning(Logger_,
fmt::format("ProcessWSFrame({}): Final Acc. Frame received but empty",
CId_));
return;
}
IncomingFrame_.append(0);

poco_trace(Logger_,
fmt::format("ProcessWSFrame({}): Final Acc. Frame received (len={}, Msg={}",
CId_, IncomingSize, IncomingFrame_.begin()));

Poco::JSON::Parser parser;
auto ParsedMessage = parser.parse(IncomingFrame_.begin());
auto IncomingJSON = ParsedMessage.extract<Poco::JSON::Object::Ptr>();

if (IncomingJSON->has(uCentralProtocol::JSONRPC)) {
if (IncomingJSON->has(uCentralProtocol::METHOD) &&
IncomingJSON->has(uCentralProtocol::PARAMS)) {
ProcessJSONRPCEvent(IncomingJSON);
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
IncomingJSON->has(uCentralProtocol::ID)) {
poco_trace(Logger_, fmt::format("RPC-RESULT({}): payload: {}", CId_,
IncomingFrame_.begin()));
ProcessJSONRPCResult(IncomingJSON);
} else {
poco_warning(
Logger_,
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
CId_, IncomingFrame_.begin()));
}
} else if (IncomingJSON->has(uCentralProtocol::RADIUS)) {
ProcessIncomingRadiusData(IncomingJSON);
} else {
std::ostringstream iS;
IncomingJSON->stringify(iS);
poco_warning(
Logger_,
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc': {}",
CId_, iS.str()));
Errors_++;
}
IncomingFrame_.clear();
IncomingFrame_.resize(0);
}

void AP_WS_Connection::ProcessIncomingFrame() {
Poco::Buffer<char> IncomingFrame(0);
Poco::Buffer<char> CurrentFrame(0);
bool KillConnection = false;
int flags = 0;
int IncomingSize = 0;

bool KillConnection=false;
try {
int Op, flags;
auto IncomingSize = WS_->receiveFrame(IncomingFrame, flags);
IncomingSize = WS_->receiveFrame(CurrentFrame, flags);
int Op;

Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;

if (IncomingSize == 0 && flags == 0 && Op == 0) {
if (IncomingSize < 0 && flags == 0) {
poco_trace(Logger_,
fmt::format("EMPTY({}): Non-blocking try-again empty frame (len={}, flags={})",
CId_, IncomingSize, flags));
} else if (IncomingSize == 0 && flags == 0) {
poco_information(Logger_,
fmt::format("DISCONNECT({}): device has disconnected. Session={}",
CId_, State_.sessionId));
return EndConnection();
}

IncomingFrame.append(0);

State_.RX += IncomingSize;
AP_WS_Server()->AddRX(IncomingSize);
if (IncomingSize > 0) {
State_.RX += IncomingSize;
AP_WS_Server()->AddRX(IncomingSize);
IncomingFrame_.append(CurrentFrame);
}
State_.MessageCount++;
State_.LastContact = Utils::Now();
poco_trace(Logger_,
fmt::format("FRAME({}): Frame rx (op={} len={}, flags={}, acc.len={})",
CId_, Op, IncomingSize, flags, IncomingFrame_.size()));

switch (Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: {
poco_trace(Logger_, fmt::format("WS-PING({}): received. PONG sent back.", CId_));
poco_trace(Logger_, fmt::format("PING({}): received. PONG sent back.", CId_));
WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);

if (KafkaManager()->Enabled()) {
Poco::JSON::Object PingObject;
Expand All @@ -643,49 +704,32 @@ namespace OpenWifi {
PingDetails.set("locale", State_.locale);
PingObject.set(uCentralProtocol::PING, PingDetails);
poco_trace(Logger_,fmt::format("Sending PING for {}", SerialNumber_));
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_,PingObject);
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_,
PingObject);
}
return;
} break;

case Poco::Net::WebSocket::FRAME_OP_PONG: {
poco_trace(Logger_, fmt::format("PONG({}): received and ignored.", CId_));
return;
} break;

case Poco::Net::WebSocket::FRAME_OP_CONT: {
poco_trace(Logger_, fmt::format("CONTINUATION({}): registered.", CId_));
} break;

case Poco::Net::WebSocket::FRAME_OP_BINARY: {
poco_trace(Logger_, fmt::format("BINARY({}): Invalid frame type.", CId_));
KillConnection=true;
return;
} break;

case Poco::Net::WebSocket::FRAME_OP_TEXT: {
poco_trace(Logger_,
fmt::format("FRAME({}): Frame received (length={}, flags={}). Msg={}",
CId_, IncomingSize, flags, IncomingFrame.begin()));

Poco::JSON::Parser parser;
auto ParsedMessage = parser.parse(IncomingFrame.begin());
auto IncomingJSON = ParsedMessage.extract<Poco::JSON::Object::Ptr>();

if (IncomingJSON->has(uCentralProtocol::JSONRPC)) {
if (IncomingJSON->has(uCentralProtocol::METHOD) &&
IncomingJSON->has(uCentralProtocol::PARAMS)) {
ProcessJSONRPCEvent(IncomingJSON);
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
IncomingJSON->has(uCentralProtocol::ID)) {
poco_trace(Logger_, fmt::format("RPC-RESULT({}): payload: {}", CId_,
IncomingFrame.begin()));
ProcessJSONRPCResult(IncomingJSON);
} else {
poco_warning(
Logger_,
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
CId_, IncomingFrame.begin()));
}
} else if (IncomingJSON->has(uCentralProtocol::RADIUS)) {
ProcessIncomingRadiusData(IncomingJSON);
} else {
std::ostringstream iS;
IncomingJSON->stringify(iS);
poco_warning(
Logger_,
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc': {}",
CId_, iS.str()));
Errors_++;
}
fmt::format("TEXT({}): Frame received (len={}, flags={}). Msg={}",
CId_, IncomingSize, flags,
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin()));
} break;

case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
Expand All @@ -701,25 +745,31 @@ namespace OpenWifi {
return;
}
}

// Check for final frame and process accumulated payload
if (!KillConnection && (flags & Poco::Net::WebSocket::FRAME_FLAG_FIN) != 0) {
ProcessWSFinalPayload();
}

} catch (const Poco::Net::ConnectionResetException &E) {
poco_warning(Logger_,
fmt::format("ConnectionResetException({}): Text:{} Payload:{} Session:{}",
CId_, E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (const Poco::JSON::JSONException &E) {
poco_warning(Logger_,
fmt::format("JSONException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (const Poco::Net::WebSocketException &E) {
poco_warning(Logger_,
fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
Expand All @@ -728,42 +778,42 @@ namespace OpenWifi {
fmt::format(
"SSLConnectionUnexpectedlyClosedException({}): Text:{} Payload:{} Session:{}",
CId_, E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (const Poco::Net::SSLException &E) {
poco_warning(Logger_,
fmt::format("SSLException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (const Poco::Net::NetException &E) {
poco_warning(Logger_,
fmt::format("NetException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (const Poco::IOException &E) {
poco_warning(Logger_,
fmt::format("IOException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (const Poco::Exception &E) {
poco_warning(Logger_,
fmt::format("Exception({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (const std::exception &E) {
poco_warning(Logger_,
fmt::format("std::exception({}): Text:{} Payload:{} Session:{}", CId_,
E.what(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
State_.sessionId));
KillConnection=true;
} catch (...) {
Expand All @@ -776,7 +826,9 @@ namespace OpenWifi {
if (!KillConnection && Errors_ < 10)
return;

poco_warning(Logger_, fmt::format("DISCONNECTING({}): ConnectionException: {} Errors: {}", CId_, KillConnection, Errors_ ));
poco_warning(Logger_,
fmt::format("DISCONNECTING({}): ConnectionException: {} Errors: {}",
CId_, KillConnection, Errors_ ));
EndConnection();
}

Expand Down Expand Up @@ -921,4 +973,4 @@ namespace OpenWifi {
}
}

} // namespace OpenWifi
} // namespace OpenWifi
4 changes: 3 additions & 1 deletion src/AP_WS_Connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace OpenWifi {
void EndConnection();
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc);
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
void ProcessWSFinalPayload();
void ProcessIncomingFrame();
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);

Expand Down Expand Up @@ -145,6 +146,7 @@ namespace OpenWifi {
std::uint64_t uuid_=0;
bool Simulated_=false;
std::atomic_uint64_t LastContact_=0;
Poco::Buffer<char> IncomingFrame_;

static inline std::atomic_uint64_t ConcurrentStartingDevices_ = 0;

Expand Down Expand Up @@ -175,4 +177,4 @@ namespace OpenWifi {

};

} // namespace OpenWifi
} // namespace OpenWifi
1 change: 0 additions & 1 deletion src/AP_WS_Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ namespace OpenWifi {
P.verificationDepth = 9;
P.loadDefaultCAs = Svr.RootCA().empty();
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
P.dhUse2048Bits = true;
P.caLocation = Svr.Cas();

auto Context = Poco::AutoPtr<Poco::Net::Context>(
Expand Down
2 changes: 1 addition & 1 deletion src/FileUploader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,4 @@ namespace OpenWifi {
poco_notice(Logger(), "Stopped...");
}

} // namespace OpenWifi
} // namespace OpenWifi
Loading
Loading