Skip to content

Commit 5dbb723

Browse files
authored
sipproxy code optimization for performance (envoyproxy#22673)
Signed-off-by: Doris Ding <[email protected]>
1 parent 9874abe commit 5dbb723

File tree

8 files changed

+110
-152
lines changed

8 files changed

+110
-152
lines changed

contrib/sip_proxy/filters/network/source/conn_manager.cc

-2
Original file line numberDiff line numberDiff line change
@@ -545,14 +545,12 @@ ConnectionManager::ActiveTrans::upstreamData(MessageMetadataSharedPtr metadata)
545545
return SipFilters::ResponseStatus::MoreData;
546546
} catch (const AppException& ex) {
547547
ENVOY_LOG(error, "sip response application error: {}", ex.what());
548-
// parent_.stats_.response_decoding_error_.inc();
549548

550549
sendLocalReply(ex, false);
551550
return SipFilters::ResponseStatus::Reset;
552551
} catch (const EnvoyException& ex) {
553552
ENVOY_CONN_LOG(error, "sip response error: {}", parent_.read_callbacks_->connection(),
554553
ex.what());
555-
// parent_.stats_.response_decoding_error_.inc();
556554

557555
onError(ex.what());
558556
return SipFilters::ResponseStatus::Reset;

contrib/sip_proxy/filters/network/source/decoder.cc

+13-31
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ int Decoder::reassemble(Buffer::Instance& data) {
152152
Buffer::OwnedImpl message{};
153153
message.move(remaining_data, full_msg_len);
154154
onDataReady(message);
155+
156+
// Even the handle of current sip message hasn't finished(async handle),
157+
// we use string of this buffer, so it can be drain safely.
155158
message.drain(message.length());
156159
full_msg_len = 0;
157160
}
@@ -227,7 +230,6 @@ Decoder::HeaderHandler::HeaderHandler(MessageHandler& parent)
227230
{HeaderType::Via, &HeaderHandler::processVia},
228231
{HeaderType::Route, &HeaderHandler::processRoute},
229232
{HeaderType::Contact, &HeaderHandler::processContact},
230-
{HeaderType::Cseq, &HeaderHandler::processCseq},
231233
{HeaderType::RRoute, &HeaderHandler::processRecordRoute},
232234
{HeaderType::SRoute, &HeaderHandler::processServiceRoute},
233235
{HeaderType::WAuth, &HeaderHandler::processWwwAuth},
@@ -237,7 +239,8 @@ Decoder::HeaderHandler::HeaderHandler(MessageHandler& parent)
237239

238240
int Decoder::HeaderHandler::processPath(absl::string_view& header) {
239241
metadata()->deleteInstipOperation(rawOffset(), header);
240-
metadata()->addEPOperation(rawOffset(), header, parent_.parent_.settings()->localServices());
242+
metadata()->addEPOperation(rawOffset(), header, HeaderType::Path,
243+
parent_.parent_.settings()->localServices());
241244
return 0;
242245
}
243246

@@ -247,7 +250,6 @@ int Decoder::HeaderHandler::processRoute(absl::string_view& header) {
247250
return 0;
248251
}
249252
setFirstRoute(false);
250-
metadata()->parseHeader(HeaderType::Route);
251253
return 0;
252254
}
253255

@@ -258,7 +260,8 @@ int Decoder::HeaderHandler::processRecordRoute(absl::string_view& header) {
258260

259261
setFirstRecordRoute(false);
260262

261-
metadata()->addEPOperation(rawOffset(), header, parent_.parent_.settings()->localServices());
263+
metadata()->addEPOperation(rawOffset(), header, HeaderType::RRoute,
264+
parent_.parent_.settings()->localServices());
262265
return 0;
263266
}
264267

@@ -300,7 +303,8 @@ int Decoder::HeaderHandler::processPCookieIPMap(absl::string_view& header) {
300303

301304
int Decoder::HeaderHandler::processContact(absl::string_view& header) {
302305
metadata()->deleteInstipOperation(rawOffset(), header);
303-
metadata()->addEPOperation(rawOffset(), header, parent_.parent_.settings()->localServices());
306+
metadata()->addEPOperation(rawOffset(), header, HeaderType::Contact,
307+
parent_.parent_.settings()->localServices());
304308
return 0;
305309
}
306310

@@ -310,16 +314,8 @@ int Decoder::HeaderHandler::processServiceRoute(absl::string_view& header) {
310314
}
311315
setFirstServiceRoute(false);
312316

313-
metadata()->addEPOperation(rawOffset(), header, parent_.parent_.settings()->localServices());
314-
return 0;
315-
}
316-
317-
//
318-
// SUBSCRIBE Header Handler
319-
//
320-
int Decoder::SUBSCRIBEHeaderHandler::processEvent(absl::string_view& header) {
321-
auto& parent = dynamic_cast<SUBSCRIBEHandler&>(this->parent_);
322-
parent.setEventType(StringUtil::trim(header.substr(header.find("Event:") + strlen("Event:"))));
317+
metadata()->addEPOperation(rawOffset(), header, HeaderType::SRoute,
318+
parent_.parent_.settings()->localServices());
323319
return 0;
324320
}
325321

@@ -384,9 +380,6 @@ void Decoder::INVITEHandler::parseHeader(HeaderType& type, absl::string_view& he
384380

385381
void Decoder::OK200Handler::parseHeader(HeaderType& type, absl::string_view& header) {
386382
switch (type) {
387-
case HeaderType::Cseq:
388-
handler_->processCseq(header);
389-
break;
390383
case HeaderType::Contact:
391384
handler_->processContact(header);
392385
break;
@@ -437,9 +430,6 @@ void Decoder::GeneralHandler::parseHeader(HeaderType& type, absl::string_view& h
437430

438431
void Decoder::SUBSCRIBEHandler::parseHeader(HeaderType& type, absl::string_view& header) {
439432
switch (type) {
440-
case HeaderType::Event:
441-
handler_->processEvent(header);
442-
break;
443433
case HeaderType::Route:
444434
handler_->processRoute(header);
445435
break;
@@ -541,7 +531,8 @@ int Decoder::decode() {
541531
absl::string_view sip_line = msg.substr(0, crlf);
542532

543533
metadata->addMsgHeader(HeaderType::TopLine, sip_line);
544-
parseTopLine(sip_line);
534+
metadata->setMsgType(sipMsgType(sip_line));
535+
metadata->setMethodType(sipMethod(sip_line));
545536
current_header_ = HeaderType::Other;
546537

547538
handler = MessageFactory::create(metadata->methodType(), *this);
@@ -585,15 +576,6 @@ int Decoder::HeaderHandler::processVia(absl::string_view& header) {
585576
return 0;
586577
}
587578

588-
int Decoder::parseTopLine(absl::string_view& top_line) {
589-
auto metadata = metadata_;
590-
metadata->setMsgType(sipMsgType(top_line));
591-
metadata->setMethodType(sipMethod(top_line));
592-
metadata->parseHeader(HeaderType::TopLine);
593-
594-
return 0;
595-
}
596-
597579
} // namespace SipProxy
598580
} // namespace NetworkFilters
599581
} // namespace Extensions

contrib/sip_proxy/filters/network/source/decoder.h

-23
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,6 @@ class Decoder : public Logger::Loggable<Logger::Id::filter> {
161161
static absl::string_view domain(absl::string_view sip_header, HeaderType header_type);
162162
static void getParamFromHeader(absl::string_view header, MessageMetadataSharedPtr metadata);
163163

164-
int parseTopLine(absl::string_view& top_line);
165-
166164
HeaderType current_header_{HeaderType::TopLine};
167165
size_t raw_offset_{0};
168166

@@ -184,15 +182,7 @@ class Decoder : public Logger::Loggable<Logger::Id::filter> {
184182
virtual int processVia(absl::string_view& header);
185183
virtual int processContact(absl::string_view& header);
186184
virtual int processPath(absl::string_view& header);
187-
virtual int processEvent(absl::string_view& header) {
188-
UNREFERENCED_PARAMETER(header);
189-
return 0;
190-
};
191185
virtual int processRoute(absl::string_view& header);
192-
virtual int processCseq(absl::string_view& header) {
193-
UNREFERENCED_PARAMETER(header);
194-
return 0;
195-
}
196186
virtual int processRecordRoute(absl::string_view& header);
197187
virtual int processServiceRoute(absl::string_view& header);
198188
virtual int processWwwAuth(absl::string_view& header);
@@ -265,7 +255,6 @@ class Decoder : public Logger::Loggable<Logger::Id::filter> {
265255
class SUBSCRIBEHeaderHandler : public HeaderHandler {
266256
public:
267257
using HeaderHandler::HeaderHandler;
268-
int processEvent(absl::string_view& header) override;
269258
};
270259

271260
class FAILURE4XXHeaderHandler : public HeaderHandler {
@@ -316,18 +305,6 @@ class Decoder : public Logger::Loggable<Logger::Id::filter> {
316305
: MessageHandler(std::make_shared<SUBSCRIBEHeaderHandler>(*this), parent) {}
317306
~SUBSCRIBEHandler() override = default;
318307
void parseHeader(HeaderType& type, absl::string_view& header) override;
319-
void setEventType(absl::string_view value) {
320-
if (value == "reg") {
321-
event_type_ = EventType::REG;
322-
} else {
323-
event_type_ = EventType::OTHERS;
324-
}
325-
}
326-
327-
private:
328-
enum class EventType { REG, OTHERS };
329-
330-
EventType event_type_;
331308
};
332309

333310
// This is used to handle Other Message

contrib/sip_proxy/filters/network/source/metadata.cc

+64-61
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,23 @@ void SipHeader::parseHeader() {
1717
}
1818

1919
std::size_t pos = 0;
20-
std::string pattern = "(.*)=(.*?)>*";
2120
absl::string_view& header = raw_text_;
21+
bool isHost = true;
2222

2323
// Has "SIP/2.0" in top line
2424
// Eg: INVITE sip:[email protected] SIP/2.0
2525
if (std::size_t found = header.find(" SIP"); found != absl::string_view::npos) {
2626
header = header.substr(0, found);
2727
}
28+
// Has message Type in header
29+
// Eg: Route: <sip:[email protected];role=anch;lr;transport=udp; \
30+
// x-suri=sip:scscf-internal.cncs.svc.cluster.local:5060;ep=10.0.0.1>
31+
if (std::size_t found = header.find(": "); found != absl::string_view::npos) {
32+
header = header.substr(found + 2);
33+
}
34+
if (std::size_t found = header.find("<"); found != absl::string_view::npos) {
35+
header = header.substr(found + 1);
36+
}
2837

2938
while (std::size_t found = header.find_first_of(";>", pos)) {
3039
absl::string_view str;
@@ -34,30 +43,55 @@ void SipHeader::parseHeader() {
3443
str = header.substr(pos, found - pos);
3544
}
3645

37-
std::string param = "";
38-
std::string value = "";
39-
re2::RE2::FullMatch(std::string(str), pattern, &param, &value);
46+
std::size_t value_pos = str.find("=");
47+
if (value_pos == absl::string_view::npos) {
48+
// First as host
49+
if (isHost) {
50+
if (str.find("sip:") != absl::string_view::npos) {
51+
str = str.substr(std::strlen("sip:"));
52+
}
4053

41-
if (!param.empty() && !value.empty()) {
42-
if (value.find("sip:") != absl::string_view::npos) {
43-
value = value.substr(std::strlen("sip:"));
44-
}
54+
if (!str.empty()) {
55+
std::size_t at = str.find('@');
56+
if (at != absl::string_view::npos) {
57+
str = str.substr(at + 1);
58+
}
59+
}
4560

46-
if (!value.empty()) {
47-
std::size_t comma = value.find(':');
48-
if (comma != absl::string_view::npos) {
49-
value = value.substr(0, comma);
61+
if (!str.empty()) {
62+
std::size_t comma = str.find(':');
63+
if (comma != absl::string_view::npos) {
64+
str = str.substr(0, comma);
65+
}
5066
}
67+
params_.emplace_back(std::make_pair("host", str));
68+
isHost = false;
5169
}
70+
} else {
71+
auto param = str.substr(0, value_pos);
72+
value_pos += 1;
73+
auto value = str.substr(value_pos);
74+
if (!param.empty() && !value.empty()) {
75+
if (value.find("sip:") != absl::string_view::npos) {
76+
value = value.substr(std::strlen("sip:"));
77+
}
78+
79+
if (!value.empty()) {
80+
std::size_t comma = value.find(':');
81+
if (comma != absl::string_view::npos) {
82+
value = value.substr(0, comma);
83+
}
84+
}
5285

53-
if (!value.empty()) {
54-
if (param == "opaque") {
55-
auto value_view = header.substr(header.find(value), value.length());
56-
params_.emplace_back(std::make_pair("ep", value_view));
57-
} else {
58-
auto param_view = header.substr(header.find(param), param.length());
59-
auto value_view = header.substr(header.find(value), value.length());
60-
params_.emplace_back(std::make_pair(param_view, value_view));
86+
if (!value.empty()) {
87+
if (param == "opaque") {
88+
auto value_view = header.substr(header.find(value), value.length());
89+
params_.emplace_back(std::make_pair("ep", value_view));
90+
} else {
91+
auto param_view = header.substr(header.find(param), param.length());
92+
auto value_view = header.substr(header.find(value), value.length());
93+
params_.emplace_back(std::make_pair(param_view, value_view));
94+
}
6195
}
6296
}
6397
}
@@ -85,7 +119,7 @@ void MessageMetadata::setTransactionId(absl::string_view data) {
85119
}
86120

87121
void MessageMetadata::addEPOperation(
88-
size_t raw_offset, absl::string_view& header,
122+
size_t raw_offset, absl::string_view& header, HeaderType type,
89123
const std::vector<envoy::extensions::filters::network::sip_proxy::v3alpha::LocalService>&
90124
local_services) {
91125
if (header.find(";ep=") != absl::string_view::npos) {
@@ -100,7 +134,7 @@ void MessageMetadata::addEPOperation(
100134
}
101135

102136
// is domain matched
103-
if (!isDomainMatched(header, local_services)) {
137+
if (!isDomainMatched(type, local_services)) {
104138
ENVOY_LOG(trace, "header {} domain is not equal to local_services domain, don't add EP.",
105139
header);
106140
return;
@@ -154,47 +188,16 @@ void MessageMetadata::addMsgHeader(HeaderType type, absl::string_view value) {
154188
}
155189
}
156190

157-
std::string MessageMetadata::getDomainFromHeaderParameter(absl::string_view& header,
158-
const std::string& parameter) {
159-
// Parameter default is host
160-
if (!parameter.empty() && parameter != "host") {
161-
auto start = header.find(parameter);
162-
if (start != absl::string_view::npos) {
163-
// service.parameter() + "="
164-
start = start + parameter.length() + strlen("=");
165-
if ("sip:" == header.substr(start, strlen("sip:"))) {
166-
start += strlen("sip:");
167-
}
168-
// end
169-
auto end = header.find_first_of(":;>", start);
170-
if (end != absl::string_view::npos) {
171-
return std::string(header.substr(start, end - start));
172-
}
173-
}
174-
}
175-
// Parameter is host
176-
// Or no domain in configured parameter, then try host
177-
auto start = header.find("sip:");
178-
if (start == absl::string_view::npos) {
179-
return "";
191+
absl::string_view MessageMetadata::getDomainFromHeaderParameter(HeaderType type,
192+
const std::string& parameter) {
193+
parseHeader(type);
194+
if ((parameter.empty() || !header(type).hasParam(parameter)) && header(type).hasParam("host")) {
195+
return header(type).param("host");
180196
}
181-
start += strlen("sip:");
182-
auto end = header.find_first_of(":;>", start);
183-
// TopLine should be absl::string_view::npos
184-
if (end == absl::string_view::npos) {
185-
end = header.length();
186-
}
187-
188-
auto addr = header.substr(start, end - start);
189-
190-
// Remove name in format of sip:name@addr:pos
191-
auto pos = addr.find("@");
192-
if (pos == absl::string_view::npos) {
193-
return std::string(header.substr(start, end - start));
194-
} else {
195-
pos += strlen("@");
196-
return std::string(addr.substr(pos, addr.length() - pos));
197+
if (header(type).hasParam(parameter)) {
198+
return header(type).param(parameter);
197199
}
200+
return "";
198201
}
199202

200203
} // namespace SipProxy

contrib/sip_proxy/filters/network/source/metadata.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,15 @@ class MessageMetadata : public Logger::Loggable<Logger::Id::filter> {
156156
};
157157

158158
void addEPOperation(
159-
size_t raw_offset, absl::string_view& header,
159+
size_t raw_offset, absl::string_view& header, HeaderType type,
160160
const std::vector<envoy::extensions::filters::network::sip_proxy::v3alpha::LocalService>&
161161
local_services);
162162
void addOpaqueOperation(size_t raw_offset, absl::string_view& header);
163163
void deleteInstipOperation(size_t raw_offset, absl::string_view& header);
164164

165165
void addMsgHeader(HeaderType type, absl::string_view value);
166166

167-
std::string getDomainFromHeaderParameter(absl::string_view& header, const std::string& parameter);
167+
absl::string_view getDomainFromHeaderParameter(HeaderType type, const std::string& parameter);
168168

169169
void parseHeader(HeaderType type, unsigned short index = 0) {
170170
return headers_[type][index].parseHeader();
@@ -214,15 +214,15 @@ class MessageMetadata : public Logger::Loggable<Logger::Id::filter> {
214214
TraContextMap tra_context_map_{};
215215

216216
bool isDomainMatched(
217-
absl::string_view& header,
217+
HeaderType type,
218218
const std::vector<envoy::extensions::filters::network::sip_proxy::v3alpha::LocalService>&
219219
local_services) {
220220
for (auto& service : local_services) {
221221
if (service.parameter().empty() || service.domain().empty()) {
222222
// no default value
223223
continue;
224224
}
225-
if (service.domain() == getDomainFromHeaderParameter(header, service.parameter())) {
225+
if (service.domain() == getDomainFromHeaderParameter(type, service.parameter())) {
226226
return true;
227227
}
228228
}

0 commit comments

Comments
 (0)