AI: GB28181: Remove embedded SIP server and enforce external SIP usage. v7.0.75 (#4466)

This PR removes the embedded GB28181 SIP server implementation from SRS
and enforces the use of external SIP servers for production deployments.

The embedded SIP server depended on the deprecated `http-parser`
library. With the planned migration to `llhttp` (which doesn't support
SIP parsing), maintaining the embedded SIP server would require
significant additional work. Since external SIP servers are already the
recommended approach for production, removing the embedded
implementation simplifies the codebase and eliminates this dependency.

Eliminated `srs_gb28181_test` from CI workflow.

Removed SIP configuration validation tests.

---------

Co-authored-by: OSSRS-AI <winlinam@gmail.com>
Co-authored-by: haibo.chen <495810242@qq.com>
This commit is contained in:
Winlin 2025-09-02 09:57:03 -04:00 committed by winlin
parent f3059d37a4
commit d9fe2c458c
14 changed files with 38 additions and 3246 deletions

View File

@ -128,8 +128,7 @@ jobs:
- name: Run SRS regression-test
run: |
docker run --rm srs:test bash -c './objs/srs -c conf/regression-test.conf && sleep 10 && \
cd 3rdparty/srs-bench && (./objs/srs_test -test.v || (cat ../../objs/srs.log && exit 1)) && \
./objs/srs_gb28181_test -test.v'
cd 3rdparty/srs-bench && (./objs/srs_test -test.v || (cat ../../objs/srs.log && exit 1))'
runs-on: ubuntu-22.04
coverage:

View File

@ -1648,32 +1648,6 @@ stream_caster {
# For gb28181 converter, listen at TCP port. for example, 9000.
# @remark We always enable bundle for media streams at this port.
listen 9000;
# SIP server for GB28181. Please note that this is only a demonstrated SIP server, please never use it in your
# online production environment. Instead please use [jsip](https://github.com/usnistgov/jsip) and there is a demo
# [srs-sip](https://github.com/ossrs/srs-sip) also base on it, for more information please see project
# [GB: External SIP](https://ossrs.io/lts/en-us/docs/v7/doc/gb28181#external-sip).
sip {
# Whether enable embedded SIP server. Please disable it if you want to use your own SIP server, see
# [GB: External SIP](https://ossrs.io/lts/en-us/docs/v7/doc/gb28181#external-sip).
# Default: on
enabled on;
# The SIP listen port, for TCP protocol.
# Default: 5060
listen 5060;
# The SIP or media transport timeout in seconds.
# Default: 60
timeout 60;
# When media disconnect, the wait time in seconds to re-invite device to publish. During this wait time, device
# might send bye or unregister message(expire is 0), so that we will cancel the re-invite.
# Default: 5
reinvite 5;
# The exposed candidate IPs, response in SDP connection line. It can be:
# * Retrieve server IP automatically, from all network interfaces.
# $CANDIDATE Read the IP from ENV variable, use * if not set.
# x.x.x.x A specified IP address or DNS name, use * if 0.0.0.0.
# Default: *
candidate *;
}
}
#

View File

@ -1,57 +0,0 @@
max_connections 1000;
daemon off;
srs_log_tank console;
# RTMP server configuration
rtmp {
listen 1935;
}
stream_caster {
enabled on;
caster gb28181;
output rtmp://127.0.0.1/live/[stream];
listen 9000;
sip {
enabled off;
}
}
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
http_api {
enabled on;
listen 1985;
}
stats {
network 0;
}
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://ossrs.io/lts/en-us/docs/v7/doc/webrtc#config-candidate
candidate $CANDIDATE;
}
vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://ossrs.io/lts/en-us/docs/v7/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://ossrs.io/lts/en-us/docs/v7/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp on;
}
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
hls {
enabled on;
}
}

View File

@ -13,12 +13,6 @@ stream_caster {
caster gb28181;
output rtmp://127.0.0.1/live/[stream];
listen 9000;
sip {
enabled on;
listen 5060;
# @see https://ossrs.io/lts/en-us/docs/v7/doc/gb28181#config-candidate
candidate $CANDIDATE;
}
}
http_server {

View File

@ -17,8 +17,7 @@ stream_caster {
# @see https://ossrs.io/lts/en-us/docs/v7/doc/gb28181#config-candidate
host $CANDIDATE;
sip {
enabled on;
listen 5060;
enabled off;
}
}

View File

@ -7,6 +7,7 @@ The changelog for SRS.
<a name="v7-changes"></a>
## SRS 7.0 Changelog
* v7.0, 2025-09-02, Merge [#4466](https://github.com/ossrs/srs/pull/4466): AI: GB28181: Remove embedded SIP server and enforce external SIP usage. v7.0.75 (#4466)
* v7.0, 2025-09-01, Merge [#4465](https://github.com/ossrs/srs/pull/4465): AI: Replace SrsSharedPtrMessage with SrsMediaPacket for unified media packet handling. v7.0.74 (#4465)
* v7.0, 2025-09-01, Merge [#4464](https://github.com/ossrs/srs/pull/4464): AI: Use shared ptr in RTMP message. v7.0.73 (#4464)
* v7.0, 2025-09-01, Merge [#4463](https://github.com/ossrs/srs/pull/4463): AI: Use SrsHttpUri for URL parsing and add legacy RTMP URL conversion. v7.0.72 (#4463)

View File

@ -3188,121 +3188,6 @@ int SrsConfig::get_stream_caster_listen(SrsConfDirective *conf)
return ::atoi(conf->arg0().c_str());
}
bool SrsConfig::get_stream_caster_sip_enable(SrsConfDirective *conf)
{
static bool DEFAULT = true;
if (!conf) {
return DEFAULT;
}
conf = conf->get("sip");
if (!conf) {
return DEFAULT;
}
conf = conf->get("enabled");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return SRS_CONF_PREFER_TRUE(conf->arg0());
}
int SrsConfig::get_stream_caster_sip_listen(SrsConfDirective *conf)
{
static int DEFAULT = 5060;
if (!conf) {
return DEFAULT;
}
conf = conf->get("sip");
if (!conf) {
return DEFAULT;
}
conf = conf->get("listen");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return ::atoi(conf->arg0().c_str());
}
srs_utime_t SrsConfig::get_stream_caster_sip_timeout(SrsConfDirective *conf)
{
static srs_utime_t DEFAULT = 60 * SRS_UTIME_SECONDS;
if (!conf) {
return DEFAULT;
}
conf = conf->get("sip");
if (!conf) {
return DEFAULT;
}
conf = conf->get("timeout");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return ::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS;
}
srs_utime_t SrsConfig::get_stream_caster_sip_reinvite(SrsConfDirective *conf)
{
static srs_utime_t DEFAULT = 5 * SRS_UTIME_SECONDS;
if (!conf) {
return DEFAULT;
}
conf = conf->get("sip");
if (!conf) {
return DEFAULT;
}
conf = conf->get("reinvite");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return ::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS;
}
std::string SrsConfig::get_stream_caster_sip_candidate(SrsConfDirective *conf)
{
static string DEFAULT = "*";
if (!conf) {
return DEFAULT;
}
conf = conf->get("sip");
if (!conf) {
return DEFAULT;
}
conf = conf->get("candidate");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
string eip = srs_getenv(conf->arg0());
if (!eip.empty()) {
return eip;
}
// If configed as ENV, but no ENV set, use default value.
if (srs_strings_starts_with(conf->arg0(), "$")) {
return DEFAULT;
}
return conf->arg0();
}
bool SrsConfig::get_rtsp_server_enabled()
{
SrsConfDirective *conf = root->get("rtsp_server");

View File

@ -484,16 +484,6 @@ public:
virtual std::string get_stream_caster_output(SrsConfDirective *conf);
// Get the listen port of stream caster.
virtual int get_stream_caster_listen(SrsConfDirective *conf);
// Get the sip.enabled configuration.
virtual bool get_stream_caster_sip_enable(SrsConfDirective *conf);
// Get the sip.listen port configuration.
virtual int get_stream_caster_sip_listen(SrsConfDirective *conf);
// Get the sip.timeout configuration.
virtual srs_utime_t get_stream_caster_sip_timeout(SrsConfDirective *conf);
// Get the sip.reinvite configuration.
virtual srs_utime_t get_stream_caster_sip_reinvite(SrsConfDirective *conf);
// Get the candidate for SDP.
virtual std::string get_stream_caster_sip_candidate(SrsConfDirective *conf);
// rtsp section
public:
virtual bool get_rtsp_server_enabled();

File diff suppressed because it is too large Load Diff

View File

@ -25,12 +25,11 @@ class SrsTcpConnection;
class SrsCoroutine;
class SrsPackContext;
class SrsBuffer;
class SrsSipMessage;
class SrsGbSession;
class SrsGbSipTcpConn;
class SrsGbMediaTcpConn;
class SrsGbSipTcpReceiver;
class SrsGbSipTcpSender;
class SrsAlonePithyPrint;
class SrsGbMuxer;
class SrsSimpleRtmpClient;
@ -58,34 +57,6 @@ enum SrsGbSessionState {
};
std::string srs_gb_session_state(SrsGbSessionState state);
// The state machine for GB SIP connection.
// init:
// to registered: Got REGISTER SIP message.
// to stable: Got MESSAGE SIP message, when SIP TCP connection re-connect.
// registered:
// to inviting: Sent INVITE SIP message.
// inviting:
// to trying: Got TRYING SIP message.
// to stable: Got INVITE 200 OK and sent INVITE OK response.
// trying:
// to stable: Got INVITE 200 OK and sent INVITE OK response.
// stable:
// to re-inviting: Sent bye to device before re-inviting.
// to bye: Got bye SIP message from device.
// re-inviting:
// to inviting: Got bye OK response from deivce.
// Please see SrsGbSipTcpConn::drive_state for detail.
enum SrsGbSipState {
SrsGbSipStateInit = 0,
SrsGbSipStateRegistered,
SrsGbSipStateInviting,
SrsGbSipStateTrying,
SrsGbSipStateReinviting,
SrsGbSipStateStable,
SrsGbSipStateBye,
};
std::string srs_gb_sip_state(SrsGbSipState state);
// For external SIP server mode, where SRS acts only as a media relay server
// 1. SIP server POST request via HTTP API with stream ID and SSRC
// 2. SRS create session using ID and SSRC, return a port for receiving media streams (indicated in conf).
@ -118,9 +89,9 @@ private:
};
// The main logic object for GB, the session.
// Each session contains a SIP object and a media object, that are managed by session. This means session always
// lives longer than SIP and media, and session will dispose SIP and media when session disposed. In another word,
// SIP and media objects use directly pointer to session, while session use shared ptr.
// Each session contains a media object, that are managed by session. This means session always
// lives longer than media, and session will dispose media when session disposed. In another word,
// media objects use directly pointer to session, while session use shared ptr.
class SrsGbSession : public ISrsResource, public ISrsCoroutineHandler, public ISrsExecutorHandler
{
private:
@ -135,23 +106,15 @@ private:
private:
SrsGbSessionState state_;
SrsSharedResource<SrsGbSipTcpConn> sip_;
SrsSharedResource<SrsGbMediaTcpConn> media_;
SrsGbMuxer *muxer_;
private:
// The candidate for SDP in configuration.
std::string candidate_;
// The public IP for SDP, generated by SRS.
std::string pip_;
// When wait for SIP and media connecting, timeout if exceed.
// When wait for media connecting, timeout if exceed.
srs_utime_t connecting_starttime_;
// The max timeout for connecting.
srs_utime_t connecting_timeout_;
// The time we enter reinviting state.
srs_utime_t reinviting_starttime_;
// The wait time for re-invite.
srs_utime_t reinvite_wait_;
// The number of timeout, dispose session if exceed.
uint32_t nn_timeout_;
@ -173,6 +136,11 @@ private:
uint64_t media_msgs_dropped_;
uint64_t media_reserved_;
public:
// The device ID generated and set by external SIP server, using SRS HTTP API. This
// device ID is used to generate the RTMP stream name.
std::string device_id_;
public:
SrsGbSession();
virtual ~SrsGbSession();
@ -189,13 +157,10 @@ public:
public:
// When got a pack of messages.
void on_ps_pack(SrsPackContext *ctx, SrsPsPacket *ps, const std::vector<SrsTsMessage *> &msgs);
// When got available SIP transport.
void on_sip_transport(SrsSharedResource<SrsGbSipTcpConn> sip);
SrsSharedResource<SrsGbSipTcpConn> sip_transport();
// When got available media transport.
void on_media_transport(SrsSharedResource<SrsGbMediaTcpConn> media);
// Get the candidate for SDP generation, the public IP address for device to connect to.
std::string pip();
// Interface ISrsCoroutineHandler
public:
virtual srs_error_t cycle();
@ -212,13 +177,12 @@ public:
virtual std::string desc();
};
// The SIP and Media listener for GB.
// The Media listener for GB.
class SrsGbListener : public ISrsListener, public ISrsTcpHandler
{
private:
SrsConfDirective *conf_;
SrsTcpListener *media_listener_;
SrsTcpListener *sip_listener_;
public:
SrsGbListener();
@ -236,174 +200,6 @@ private:
srs_error_t listen_api();
};
// A GB28181 TCP SIP connection.
class SrsGbSipTcpConn : public ISrsResource, public ISrsCoroutineHandler, public ISrsExecutorHandler
{
private:
SrsGbSipState state_;
// The owner session object, note that we use the raw pointer and should never free it.
SrsGbSession *session_;
SrsSipMessage *register_;
SrsSipMessage *invite_ok_;
private:
std::string ssrc_str_;
uint32_t ssrc_v_;
private:
SrsConfDirective *conf_;
SrsTcpListener *sip_listener_;
SrsTcpListener *media_listener_;
private:
// The shared resource which own this object, we should never free it because it's managed by shared ptr.
SrsSharedResource<SrsGbSipTcpConn> *wrapper_;
// The owner coroutine, allow user to interrupt the loop.
ISrsInterruptable *owner_coroutine_;
ISrsContextIdSetter *owner_cid_;
SrsContextId cid_;
private:
SrsTcpConnection *conn_;
SrsGbSipTcpReceiver *receiver_;
SrsGbSipTcpSender *sender_;
public:
SrsGbSipTcpConn();
virtual ~SrsGbSipTcpConn();
public:
// Setup object, to keep empty constructor.
void setup(SrsConfDirective *conf, SrsTcpListener *sip, SrsTcpListener *media, srs_netfd_t stfd);
// Setup the owner, the wrapper is the shared ptr, the interruptable object is the coroutine, and the cid is the context id.
void setup_owner(SrsSharedResource<SrsGbSipTcpConn> *wrapper, ISrsInterruptable *owner_coroutine, ISrsContextIdSetter *owner_cid);
// Interface ISrsExecutorHandler
public:
virtual void on_executor_done(ISrsInterruptable *executor);
public:
// Get the SIP device id.
std::string device_id();
// For use with external SIP signaling server ONLY
// When using an external SIP signaling server, device id are not available, so manual configuration is required
// This id will be used as the stream name in the RTMP protocol
void set_device_id(const std::string &id);
// Set the cid of all coroutines.
virtual void set_cid(const SrsContextId &cid);
private:
// Get the sip and media listen port.
void query_ports(int *sip, int *media);
public:
// When got a SIP message.
srs_error_t on_sip_message(SrsSipMessage *msg);
// Enqueue a SIP message to send, which might be a request or response.
void enqueue_sip_message(SrsSipMessage *msg);
private:
void drive_state(SrsSipMessage *msg);
void register_response(SrsSipMessage *msg);
void message_response(SrsSipMessage *msg, http_status status);
void invite_ack(SrsSipMessage *msg);
void bye_response(SrsSipMessage *msg);
public:
srs_error_t invite_request(uint32_t *pssrc);
public:
// Interrupt transport by session.
void interrupt();
// Get the SIP state.
SrsGbSipState state();
// Reset the SIP state to registered, for re-inviting.
void reset_to_register();
// Whether SIP state is registered or more.
bool is_registered();
// Whether SIP state is stable state, established.
bool is_stable();
// Whether SIP is bye bye.
bool is_bye();
private:
SrsGbSipState set_state(SrsGbSipState v);
// Interface ISrsResource
public:
virtual const SrsContextId &get_id();
virtual std::string desc();
// Interface ISrsCoroutineHandler
public:
virtual srs_error_t cycle();
private:
srs_error_t do_cycle();
private:
// Create session if no one, or bind to an existed session.
srs_error_t bind_session(SrsSipMessage *msg, SrsGbSession **psession);
};
// Start a coroutine to receive SIP messages.
class SrsGbSipTcpReceiver : public ISrsStartable, public ISrsCoroutineHandler
{
private:
SrsCoroutine *trd_;
SrsTcpConnection *conn_;
SrsGbSipTcpConn *sip_;
public:
SrsGbSipTcpReceiver(SrsGbSipTcpConn *sip, SrsTcpConnection *conn);
virtual ~SrsGbSipTcpReceiver();
public:
// Interrupt the receiver coroutine.
void interrupt();
// Set the cid of all coroutines.
virtual void set_cid(const SrsContextId &cid);
// Interface ISrsStartable
public:
virtual srs_error_t start();
// Interface ISrsCoroutineHandler
public:
virtual srs_error_t cycle();
private:
srs_error_t do_cycle();
};
// Start a coroutine to send out SIP messages.
class SrsGbSipTcpSender : public ISrsStartable, public ISrsCoroutineHandler
{
private:
SrsCoroutine *trd_;
SrsTcpConnection *conn_;
private:
std::vector<SrsSipMessage *> msgs_;
srs_cond_t wait_;
public:
SrsGbSipTcpSender(SrsTcpConnection *conn);
virtual ~SrsGbSipTcpSender();
public:
// Push message to queue, and sender will send out in dedicate coroutine.
void enqueue(SrsSipMessage *msg);
// Interrupt the sender coroutine.
void interrupt();
// Set the cid of all coroutines.
virtual void set_cid(const SrsContextId &cid);
// Interface ISrsStartable
public:
virtual srs_error_t start();
// Interface ISrsCoroutineHandler
public:
virtual srs_error_t cycle();
private:
srs_error_t do_cycle();
};
// The handler for a pack of PS PES packets.
class ISrsPsPackHandler
{
@ -557,156 +353,6 @@ private:
virtual void close();
};
// Response writer for SIP.
class SrsSipResponseWriter : public SrsHttpResponseWriter
{
public:
SrsSipResponseWriter(ISrsProtocolReadWriter *io);
virtual ~SrsSipResponseWriter();
// Interface ISrsHttpFirstLineWriter
public:
virtual srs_error_t build_first_line(std::stringstream &ss, char *data, int size);
};
// Request writer for SIP.
class SrsSipRequestWriter : public SrsHttpRequestWriter
{
public:
SrsSipRequestWriter(ISrsProtocolReadWriter *io);
virtual ~SrsSipRequestWriter();
// Interface ISrsHttpFirstLineWriter
public:
virtual srs_error_t build_first_line(std::stringstream &ss, char *data, int size);
};
// SIP message, covert with HTTP message.
class SrsSipMessage
{
public:
// SIP message type, request or response.
http_parser_type type_;
// For SIP request.
http_method method_; // For example: HTTP_INVITE
std::string request_uri_; // For example: sip:34020000001320000001@3402000000
std::string request_uri_user_; // For example: 34020000001320000001
std::string request_uri_host_; // For example: 3402000000
// For SIP response.
http_status status_; // For example: HTTP_STATUS_OK
public:
// The Via header field indicates the path taken by the request so far and indicates the path that should be
// followed in routing responses. See https://www.ietf.org/rfc/rfc3261.html#section-20.42
// @param transport TCP or UDP, the transport protocol.
// @param send_by The host and port which send the packet.
// @param branch Transaction identifier, see https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.7
// @param rport For UDP to traverse NATs, see https://www.ietf.org/rfc/rfc3581.html
std::string via_; // For example: SIP/2.0/TCP 192.168.3.82:5060;rport;branch=z9hG4bK0l31rx
std::string via_transport_; // For example: TCP
std::string via_send_by_; // For example: 192.168.3.82:5060
std::string via_send_by_address_; // For example: 192.168.3.82
int via_send_by_port_; // For example: 5060
std::string via_branch_; // For example: branch=z9hG4bK0l31rx
std::string via_rport_; // For example: rport
public:
// See https://www.ietf.org/rfc/rfc3261.html#section-20.20
// See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.3
std::string from_; // For example: <sip:34020000002000000001@3402000000>;tag=SRSk1er282t
std::string from_address_; // For example: <sip:34020000002000000001@3402000000>
std::string from_address_user_; // For example: 34020000002000000001
std::string from_address_host_; // For example: 3402000000
std::string from_tag_; // For example: tag=SRSk1er282t
public:
// See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.2
// See https://www.ietf.org/rfc/rfc3261.html#section-20.39
std::string to_; // For example: <sip:34020000001320000001@3402000000>;tag=SRSk1er282t
std::string to_address_; // For example: <sip:34020000001320000001@3402000000>
std::string to_address_user_; // For example: 34020000001320000001
std::string to_address_host_; // For example: 3402000000
std::string to_tag_; // For example: tag=SRSk1er282t
public:
// See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.4
// See https://www.ietf.org/rfc/rfc3261.html#section-20.8
std::string call_id_; // For example: 854k7337207yxpfj
// See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.8
// See https://www.ietf.org/rfc/rfc3261.html#section-20.10
std::string contact_; // For example: <sip:34020000002000000001@3402000000>
std::string contact_user_; // For example: <sip:34020000002000000001@3402000000>
std::string contact_host_; // For example: 3402000000
std::string contact_host_address_; // For example: 3402000000
int contact_host_port_; // For example: 5060
// See https://www.ietf.org/rfc/rfc3261.html#section-20.19
uint32_t expires_;
// See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.6
// See https://www.ietf.org/rfc/rfc3261.html#section-20.22
uint32_t max_forwards_;
public:
// See https://www.ietf.org/rfc/rfc3261.html#section-8.1.1.5
// See https://www.ietf.org/rfc/rfc3261.html#section-20.16
std::string cseq_;
uint32_t cseq_number_;
std::string cseq_method_;
public:
// See https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=469659DC56B9B8187671FF08748CEC89
std::string subject_;
// The content type.
std::string content_type_;
public:
// SIP message body.
std::string body_;
// Escape \r to \\r, \n to \\n.
std::string body_escaped_;
public:
SrsSipMessage();
virtual ~SrsSipMessage();
public:
SrsSipMessage *copy();
const std::string &device_id();
std::string ssrc_domain_id();
SrsSipMessage *set_body(std::string v);
srs_error_t parse(ISrsHttpMessage *m);
private:
srs_error_t parse_via(const std::string &via);
srs_error_t parse_from(const std::string &from);
srs_error_t parse_to(const std::string &to);
srs_error_t parse_cseq(const std::string &cseq);
srs_error_t parse_contact(const std::string &contact);
public:
bool is_register()
{
return type_ == HTTP_REQUEST && method_ == HTTP_REGISTER;
}
bool is_message()
{
return type_ == HTTP_REQUEST && method_ == HTTP_MESSAGE;
}
bool is_invite()
{
return type_ == HTTP_REQUEST && method_ == HTTP_INVITE;
}
bool is_trying()
{
return type_ == HTTP_RESPONSE && cseq_method_ == "INVITE" && status_ == HTTP_STATUS_CONTINUE;
}
bool is_invite_ok()
{
return type_ == HTTP_RESPONSE && cseq_method_ == "INVITE" && status_ == HTTP_STATUS_OK;
}
bool is_bye()
{
return type_ == HTTP_REQUEST && method_ == HTTP_BYE;
}
bool is_bye_ok()
{
return type_ == HTTP_RESPONSE && cseq_method_ == "BYE" && status_ == HTTP_STATUS_OK;
}
};
// Recoverable PS context for GB28181.
class SrsRecoverablePsContext
{
@ -774,16 +420,6 @@ public:
// Find the pack header which starts with bytes (00 00 01 ba).
extern bool srs_skip_util_pack(SrsBuffer *stream);
// Parse the address from SIP string, for example:
// sip:bob@ossrs.io:5060
// <sip:bob@ossrs.io:5060>
// Bob <sip:bob@ossrs.io:5060>
// Parsed as:
// user: bob
// host: ossrs.io:5060
// Note that the host can be parsed by srs_net_split_hostport as host(ossrs.io) and port(5060).
extern void srs_sip_parse_address(const std::string &address, std::string &user, std::string &host);
// Manager for GB connections.
extern SrsResourceManager *_srs_gb_manager;

View File

@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
#define VERSION_REVISION 74
#define VERSION_REVISION 75
#endif

View File

@ -1979,12 +1979,6 @@ enum state { s_dead = 1 /* important that this is > 0 */
s_res_HT,
s_res_HTT,
s_res_HTTP,
s_res_S /* SIP https://www.ietf.org/rfc/rfc3261.html */
,
s_res_SI /* SIP https://www.ietf.org/rfc/rfc3261.html */
,
s_res_SIP /* SIP https://www.ietf.org/rfc/rfc3261.html */
,
s_res_http_major,
s_res_http_dot,
s_res_http_minor,
@ -2019,12 +2013,6 @@ enum state { s_dead = 1 /* important that this is > 0 */
s_req_http_HTTP,
s_req_http_I,
s_req_http_IC,
s_req_http_S /* SIP https://www.ietf.org/rfc/rfc3261.html */
,
s_req_http_SI /* SIP https://www.ietf.org/rfc/rfc3261.html */
,
s_req_http_SIP /* SIP https://www.ietf.org/rfc/rfc3261.html */
,
s_req_http_major,
s_req_http_dot,
s_req_http_minor,
@ -2442,11 +2430,6 @@ size_t http_parser_execute(http_parser *parser,
if (ch == 'H') {
UPDATE_STATE(s_res_or_resp_H);
CALLBACK_NOTIFY(message_begin);
} else if (ch == 'S') { /* SIP https://www.ietf.org/rfc/rfc3261.html */
parser->type = HTTP_RESPONSE;
UPDATE_STATE(s_res_S);
CALLBACK_NOTIFY(message_begin);
} else {
parser->type = HTTP_REQUEST;
@ -2482,8 +2465,6 @@ size_t http_parser_execute(http_parser *parser,
if (ch == 'H') {
UPDATE_STATE(s_res_H);
} else if (ch == 'S') { /* SIP https://www.ietf.org/rfc/rfc3261.html */
UPDATE_STATE(s_res_S);
} else {
SET_ERRNO(HPE_INVALID_CONSTANT);
goto error;
@ -2513,24 +2494,6 @@ size_t http_parser_execute(http_parser *parser,
UPDATE_STATE(s_res_http_major);
break;
/* SIP https://www.ietf.org/rfc/rfc3261.html */
case s_res_S:
STRICT_CHECK(ch != 'I');
UPDATE_STATE(s_res_SI);
break;
/* SIP https://www.ietf.org/rfc/rfc3261.html */
case s_res_SI:
STRICT_CHECK(ch != 'P');
UPDATE_STATE(s_res_SIP);
break;
/* SIP https://www.ietf.org/rfc/rfc3261.html */
case s_res_SIP:
STRICT_CHECK(ch != '/');
UPDATE_STATE(s_res_http_major);
break;
case s_res_http_major:
if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION);
@ -2677,9 +2640,6 @@ size_t http_parser_execute(http_parser *parser,
case 'H':
parser->method = HTTP_HEAD;
break;
case 'I':
parser->method = HTTP_INVITE;
break; /* SIP https://www.ietf.org/rfc/rfc3261.html */
case 'L':
parser->method = HTTP_LOCK; /* or LINK */
break;
@ -2743,8 +2703,6 @@ size_t http_parser_execute(http_parser *parser,
XX(POST, 1, 'A', PATCH)
XX(POST, 1, 'R', PROPFIND)
XX(PUT, 2, 'R', PURGE)
XX(ACL, 2, 'K', ACK) /* SIP https://www.ietf.org/rfc/rfc3261.html */
XX(BIND, 1, 'Y', BYE) /* SIP https://www.ietf.org/rfc/rfc3261.html */
XX(CONNECT, 1, 'H', CHECKOUT)
XX(CONNECT, 2, 'P', COPY)
XX(MKCOL, 1, 'O', MOVE)
@ -2752,11 +2710,9 @@ size_t http_parser_execute(http_parser *parser,
XX(MKCOL, 1, '-', MSEARCH)
XX(MKCOL, 2, 'A', MKACTIVITY)
XX(MKCOL, 3, 'A', MKCALENDAR)
XX(MERGE, 2, 'S', MESSAGE) /* SIP https://www.ietf.org/rfc/rfc3261.html */
XX(SUBSCRIBE, 1, 'E', SEARCH)
XX(SUBSCRIBE, 1, 'O', SOURCE)
XX(REPORT, 2, 'B', REBIND)
XX(REPORT, 2, 'G', REGISTER) /* SIP https://www.ietf.org/rfc/rfc3261.html */
XX(PROPFIND, 4, 'P', PROPPATCH)
XX(LOCK, 1, 'I', LINK)
XX(UNLOCK, 2, 'S', UNSUBSCRIBE)
@ -2785,11 +2741,6 @@ size_t http_parser_execute(http_parser *parser,
UPDATE_STATE(s_req_server_start);
}
/* SIP https://www.ietf.org/rfc/rfc3261.html */
if (parser->method >= HTTP_REGISTER && parser->method <= HTTP_BYE) {
UPDATE_STATE(s_req_path);
}
UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
if (UNLIKELY(CURRENT_STATE() == s_dead)) {
SET_ERRNO(HPE_INVALID_URL);
@ -2857,9 +2808,6 @@ size_t http_parser_execute(http_parser *parser,
case 'H':
UPDATE_STATE(s_req_http_H);
break;
case 'S': /* SIP https://www.ietf.org/rfc/rfc3261.html */
UPDATE_STATE(s_req_http_S); /* SIP https://www.ietf.org/rfc/rfc3261.html */
break; /* SIP https://www.ietf.org/rfc/rfc3261.html */
case 'I':
if (parser->method == HTTP_SOURCE) {
UPDATE_STATE(s_req_http_I);
@ -2902,24 +2850,6 @@ size_t http_parser_execute(http_parser *parser,
UPDATE_STATE(s_req_http_major);
break;
/* SIP https://www.ietf.org/rfc/rfc3261.html */
case s_req_http_S:
STRICT_CHECK(ch != 'I');
UPDATE_STATE(s_req_http_SI);
break;
/* SIP https://www.ietf.org/rfc/rfc3261.html */
case s_req_http_SI:
STRICT_CHECK(ch != 'P');
UPDATE_STATE(s_req_http_SIP);
break;
/* SIP https://www.ietf.org/rfc/rfc3261.html */
case s_req_http_SIP:
STRICT_CHECK(ch != '/');
UPDATE_STATE(s_req_http_major);
break;
case s_req_http_major:
if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION);

View File

@ -905,13 +905,7 @@ enum http_status {
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
XX(33, SOURCE, SOURCE) \
/* SIP https://www.ietf.org/rfc/rfc3261.html */ \
XX(34, REGISTER, REGISTER) \
XX(35, INVITE, INVITE) \
XX(36, ACK, ACK) \
XX(37, MESSAGE, MESSAGE) \
XX(38, BYE, BYE)
XX(33, SOURCE, SOURCE)
enum http_method {
#define XX(num, name, string) HTTP_##name = num,

File diff suppressed because it is too large Load Diff