winlin

srs-librtmp support hijack io apis for st-load. 2.0.42.

@@ -485,6 +485,7 @@ Supported operating systems and hardware: @@ -485,6 +485,7 @@ Supported operating systems and hardware:
485 * 2013-10-17, Created.<br/> 485 * 2013-10-17, Created.<br/>
486 486
487 ## History 487 ## History
  488 +* v2.0, 2014-12-02, srs-librtmp support hijack io apis for st-load. 2.0.42.
488 * v2.0, 2014-12-01, for [#237](https://github.com/winlinvip/simple-rtmp-server/issues/237), refine syscall for recv, supports 1.5k clients. 2.0.41. 489 * v2.0, 2014-12-01, for [#237](https://github.com/winlinvip/simple-rtmp-server/issues/237), refine syscall for recv, supports 1.5k clients. 2.0.41.
489 * v2.0, 2014-11-30, add qtcreate project file trunk/src/qt/srs/srs-qt.pro. 2.0.39. 490 * v2.0, 2014-11-30, add qtcreate project file trunk/src/qt/srs/srs-qt.pro. 2.0.39.
490 * v2.0, 2014-11-29, fix [#235](https://github.com/winlinvip/simple-rtmp-server/issues/235), refine handshake, replace union with template method. 2.0.38. 491 * v2.0, 2014-11-29, fix [#235](https://github.com/winlinvip/simple-rtmp-server/issues/235), refine handshake, replace union with template method. 2.0.38.
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 41 34 +#define VERSION_REVISION 42
35 // server info. 35 // server info.
36 #define RTMP_SIG_SRS_KEY "SRS" 36 #define RTMP_SIG_SRS_KEY "SRS"
37 #define RTMP_SIG_SRS_ROLE "origin/edge server" 37 #define RTMP_SIG_SRS_ROLE "origin/edge server"
@@ -43,188 +43,305 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -43,188 +43,305 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 #define ST_UTIME_NO_TIMEOUT -1 43 #define ST_UTIME_NO_TIMEOUT -1
44 #endif 44 #endif
45 45
  46 +// when io not hijacked, use simple socket, the block sync stream.
  47 +#ifndef SRS_HIJACK_IO
  48 + struct SrsBlockSyncSocket
  49 + {
  50 + SOCKET fd;
  51 + int64_t recv_timeout;
  52 + int64_t send_timeout;
  53 + int64_t recv_bytes;
  54 + int64_t send_bytes;
  55 +
  56 + SrsBlockSyncSocket() {
  57 + send_timeout = recv_timeout = ST_UTIME_NO_TIMEOUT;
  58 + recv_bytes = send_bytes = 0;
  59 +
  60 + SOCKET_RESET(fd);
  61 + SOCKET_SETUP();
  62 + }
  63 +
  64 + virtual ~SrsBlockSyncSocket() {
  65 + SOCKET_CLOSE(fd);
  66 + SOCKET_CLEANUP();
  67 + }
  68 + };
  69 + srs_hijack_io_t srs_hijack_io_create()
  70 + {
  71 + SrsBlockSyncSocket* skt = new SrsBlockSyncSocket();
  72 + return skt;
  73 + }
  74 + void srs_hijack_io_destroy(srs_hijack_io_t ctx)
  75 + {
  76 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  77 + srs_freep(skt);
  78 + }
  79 + int srs_hijack_io_create_socket(srs_hijack_io_t ctx)
  80 + {
  81 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  82 +
  83 + skt->fd = ::socket(AF_INET, SOCK_STREAM, 0);
  84 + if (!SOCKET_VALID(skt->fd)) {
  85 + return ERROR_SOCKET_CREATE;
  86 + }
  87 +
  88 + return ERROR_SUCCESS;
  89 + }
  90 + int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port)
  91 + {
  92 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  93 +
  94 + sockaddr_in addr;
  95 + addr.sin_family = AF_INET;
  96 + addr.sin_port = htons(port);
  97 + addr.sin_addr.s_addr = inet_addr(server_ip);
  98 +
  99 + if(::connect(skt->fd, (const struct sockaddr*)&addr, sizeof(sockaddr_in)) < 0){
  100 + return ERROR_SOCKET_CONNECT;
  101 + }
  102 +
  103 + return ERROR_SUCCESS;
  104 + }
  105 + int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread)
  106 + {
  107 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  108 +
  109 + int ret = ERROR_SUCCESS;
  110 +
  111 + ssize_t nb_read = ::recv(skt->fd, (char*)buf, size, 0);
  112 +
  113 + if (nread) {
  114 + *nread = nb_read;
  115 + }
  116 +
  117 + // On success a non-negative integer indicating the number of bytes actually read is returned
  118 + // (a value of 0 means the network connection is closed or end of file is reached).
  119 + if (nb_read <= 0) {
  120 + if (nb_read < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
  121 + return ERROR_SOCKET_TIMEOUT;
  122 + }
  123 +
  124 + if (nb_read == 0) {
  125 + errno = SOCKET_ECONNRESET;
  126 + }
  127 +
  128 + return ERROR_SOCKET_READ;
  129 + }
  130 +
  131 + skt->recv_bytes += nb_read;
  132 +
  133 + return ret;
  134 + }
  135 + void srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us)
  136 + {
  137 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  138 + skt->recv_timeout = timeout_us;
  139 + }
  140 + int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx)
  141 + {
  142 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  143 + return skt->recv_timeout;
  144 + }
  145 + int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx)
  146 + {
  147 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  148 + return skt->recv_bytes;
  149 + }
  150 + void srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t timeout_us)
  151 + {
  152 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  153 + skt->send_timeout = timeout_us;
  154 + }
  155 + int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx)
  156 + {
  157 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  158 + return skt->send_timeout;
  159 + }
  160 + int64_t srs_hijack_io_get_send_bytes(srs_hijack_io_t ctx)
  161 + {
  162 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  163 + return skt->send_bytes;
  164 + }
  165 + int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ssize_t* nwrite)
  166 + {
  167 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  168 +
  169 + int ret = ERROR_SUCCESS;
  170 +
  171 + ssize_t nb_write = ::writev(skt->fd, iov, iov_size);
  172 +
  173 + if (nwrite) {
  174 + *nwrite = nb_write;
  175 + }
  176 +
  177 + // On success, the readv() function returns the number of bytes read;
  178 + // the writev() function returns the number of bytes written. On error, -1 is
  179 + // returned, and errno is set appropriately.
  180 + if (nb_write <= 0) {
  181 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/200
  182 + if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
  183 + return ERROR_SOCKET_TIMEOUT;
  184 + }
  185 +
  186 + return ERROR_SOCKET_WRITE;
  187 + }
  188 +
  189 + skt->send_bytes += nb_write;
  190 +
  191 + return ret;
  192 + }
  193 + bool srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t timeout_us)
  194 + {
  195 + return timeout_us == (int64_t)ST_UTIME_NO_TIMEOUT;
  196 + }
  197 + int srs_hijack_io_read_fully(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread)
  198 + {
  199 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  200 +
  201 + int ret = ERROR_SUCCESS;
  202 +
  203 + size_t left = size;
  204 + ssize_t nb_read = 0;
  205 +
  206 + while (left > 0) {
  207 + char* this_buf = (char*)buf + nb_read;
  208 + ssize_t this_nread;
  209 +
  210 + if ((ret = srs_hijack_io_read(ctx, this_buf, left, &this_nread)) != ERROR_SUCCESS) {
  211 + return ret;
  212 + }
  213 +
  214 + nb_read += this_nread;
  215 + left -= (size_t)this_nread;
  216 + }
  217 +
  218 + if (nread) {
  219 + *nread = nb_read;
  220 + }
  221 + skt->recv_bytes += nb_read;
  222 +
  223 + return ret;
  224 + }
  225 + int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite)
  226 + {
  227 + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
  228 +
  229 + int ret = ERROR_SUCCESS;
  230 +
  231 + ssize_t nb_write = ::send(skt->fd, (char*)buf, size, 0);
  232 +
  233 + if (nwrite) {
  234 + *nwrite = nb_write;
  235 + }
  236 +
  237 + if (nb_write <= 0) {
  238 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/200
  239 + if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
  240 + return ERROR_SOCKET_TIMEOUT;
  241 + }
  242 +
  243 + return ERROR_SOCKET_WRITE;
  244 + }
  245 +
  246 + skt->send_bytes += nb_write;
  247 +
  248 + return ret;
  249 + }
  250 +#endif
  251 +
46 SimpleSocketStream::SimpleSocketStream() 252 SimpleSocketStream::SimpleSocketStream()
47 { 253 {
48 - SOCKET_RESET(fd);  
49 - send_timeout = recv_timeout = ST_UTIME_NO_TIMEOUT;  
50 - recv_bytes = send_bytes = 0;  
51 - SOCKET_SETUP(); 254 + io = srs_hijack_io_create();
52 } 255 }
53 256
54 SimpleSocketStream::~SimpleSocketStream() 257 SimpleSocketStream::~SimpleSocketStream()
55 { 258 {
56 - SOCKET_CLOSE(fd);  
57 - SOCKET_CLEANUP(); 259 + if (io) {
  260 + srs_hijack_io_destroy(io);
  261 + io = NULL;
  262 + }
58 } 263 }
59 264
60 int SimpleSocketStream::create_socket() 265 int SimpleSocketStream::create_socket()
61 { 266 {
62 - fd = ::socket(AF_INET, SOCK_STREAM, 0);  
63 - if (!SOCKET_VALID(fd)) {  
64 - return ERROR_SOCKET_CREATE;  
65 - }  
66 -  
67 - return ERROR_SUCCESS; 267 + srs_assert(io);
  268 + return srs_hijack_io_create_socket(io);
68 } 269 }
69 270
70 int SimpleSocketStream::connect(const char* server_ip, int port) 271 int SimpleSocketStream::connect(const char* server_ip, int port)
71 { 272 {
72 - sockaddr_in addr;  
73 - addr.sin_family = AF_INET;  
74 - addr.sin_port = htons(port);  
75 - addr.sin_addr.s_addr = inet_addr(server_ip);  
76 -  
77 - if(::connect(fd, (const struct sockaddr*)&addr, sizeof(sockaddr_in)) < 0){  
78 - return ERROR_SOCKET_CONNECT;  
79 - }  
80 -  
81 - return ERROR_SUCCESS; 273 + srs_assert(io);
  274 + return srs_hijack_io_connect(io, server_ip, port);
82 } 275 }
83 276
84 // ISrsBufferReader 277 // ISrsBufferReader
85 int SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread) 278 int SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread)
86 { 279 {
87 - int ret = ERROR_SUCCESS;  
88 -  
89 - ssize_t nb_read = ::recv(fd, (char*)buf, size, 0);  
90 -  
91 - if (nread) {  
92 - *nread = nb_read;  
93 - }  
94 -  
95 - // On success a non-negative integer indicating the number of bytes actually read is returned  
96 - // (a value of 0 means the network connection is closed or end of file is reached).  
97 - if (nb_read <= 0) {  
98 - if (nb_read < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {  
99 - return ERROR_SOCKET_TIMEOUT;  
100 - }  
101 -  
102 - if (nb_read == 0) {  
103 - errno = SOCKET_ECONNRESET;  
104 - }  
105 -  
106 - return ERROR_SOCKET_READ;  
107 - }  
108 -  
109 - recv_bytes += nb_read;  
110 -  
111 - return ret; 280 + srs_assert(io);
  281 + return srs_hijack_io_read(io, buf, size, nread);
112 } 282 }
113 283
114 // ISrsProtocolReader 284 // ISrsProtocolReader
115 void SimpleSocketStream::set_recv_timeout(int64_t timeout_us) 285 void SimpleSocketStream::set_recv_timeout(int64_t timeout_us)
116 { 286 {
117 - recv_timeout = timeout_us; 287 + srs_assert(io);
  288 + srs_hijack_io_set_recv_timeout(io, timeout_us);
118 } 289 }
119 290
120 int64_t SimpleSocketStream::get_recv_timeout() 291 int64_t SimpleSocketStream::get_recv_timeout()
121 { 292 {
122 - return recv_timeout; 293 + srs_assert(io);
  294 + return srs_hijack_io_get_recv_timeout(io);
123 } 295 }
124 296
125 int64_t SimpleSocketStream::get_recv_bytes() 297 int64_t SimpleSocketStream::get_recv_bytes()
126 { 298 {
127 - return recv_bytes; 299 + srs_assert(io);
  300 + return srs_hijack_io_get_recv_bytes(io);
128 } 301 }
129 302
130 // ISrsProtocolWriter 303 // ISrsProtocolWriter
131 void SimpleSocketStream::set_send_timeout(int64_t timeout_us) 304 void SimpleSocketStream::set_send_timeout(int64_t timeout_us)
132 { 305 {
133 - send_timeout = timeout_us; 306 + srs_assert(io);
  307 + srs_hijack_io_set_send_timeout(io, timeout_us);
134 } 308 }
135 309
136 int64_t SimpleSocketStream::get_send_timeout() 310 int64_t SimpleSocketStream::get_send_timeout()
137 { 311 {
138 - return send_timeout; 312 + srs_assert(io);
  313 + return srs_hijack_io_get_send_timeout(io);
139 } 314 }
140 315
141 int64_t SimpleSocketStream::get_send_bytes() 316 int64_t SimpleSocketStream::get_send_bytes()
142 { 317 {
143 - return send_bytes; 318 + srs_assert(io);
  319 + return srs_hijack_io_get_send_bytes(io);
144 } 320 }
145 321
146 int SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t* nwrite) 322 int SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t* nwrite)
147 { 323 {
148 - int ret = ERROR_SUCCESS;  
149 -  
150 - ssize_t nb_write = ::writev(fd, iov, iov_size);  
151 -  
152 - if (nwrite) {  
153 - *nwrite = nb_write;  
154 - }  
155 -  
156 - // On success, the readv() function returns the number of bytes read;  
157 - // the writev() function returns the number of bytes written. On error, -1 is  
158 - // returned, and errno is set appropriately.  
159 - if (nb_write <= 0) {  
160 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/200  
161 - if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {  
162 - return ERROR_SOCKET_TIMEOUT;  
163 - }  
164 -  
165 - return ERROR_SOCKET_WRITE;  
166 - }  
167 -  
168 - send_bytes += nb_write;  
169 -  
170 - return ret; 324 + srs_assert(io);
  325 + return srs_hijack_io_writev(io, iov, iov_size, nwrite);
171 } 326 }
172 327
173 // ISrsProtocolReaderWriter 328 // ISrsProtocolReaderWriter
174 bool SimpleSocketStream::is_never_timeout(int64_t timeout_us) 329 bool SimpleSocketStream::is_never_timeout(int64_t timeout_us)
175 { 330 {
176 - return timeout_us == (int64_t)ST_UTIME_NO_TIMEOUT; 331 + srs_assert(io);
  332 + return srs_hijack_io_is_never_timeout(io, timeout_us);
177 } 333 }
178 334
179 int SimpleSocketStream::read_fully(void* buf, size_t size, ssize_t* nread) 335 int SimpleSocketStream::read_fully(void* buf, size_t size, ssize_t* nread)
180 { 336 {
181 - int ret = ERROR_SUCCESS;  
182 -  
183 - size_t left = size;  
184 - ssize_t nb_read = 0;  
185 -  
186 - while (left > 0) {  
187 - char* this_buf = (char*)buf + nb_read;  
188 - ssize_t this_nread;  
189 -  
190 - if ((ret = this->read(this_buf, left, &this_nread)) != ERROR_SUCCESS) {  
191 - return ret;  
192 - }  
193 -  
194 - nb_read += this_nread;  
195 - left -= (size_t)this_nread;  
196 - }  
197 -  
198 - if (nread) {  
199 - *nread = nb_read;  
200 - }  
201 - recv_bytes += nb_read;  
202 -  
203 - return ret; 337 + srs_assert(io);
  338 + return srs_hijack_io_read_fully(io, buf, size, nread);
204 } 339 }
205 340
206 int SimpleSocketStream::write(void* buf, size_t size, ssize_t* nwrite) 341 int SimpleSocketStream::write(void* buf, size_t size, ssize_t* nwrite)
207 { 342 {
208 - int ret = ERROR_SUCCESS;  
209 -  
210 - ssize_t nb_write = ::send(fd, (char*)buf, size, 0);  
211 -  
212 - if (nwrite) {  
213 - *nwrite = nb_write;  
214 - }  
215 -  
216 - if (nb_write <= 0) {  
217 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/200  
218 - if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {  
219 - return ERROR_SOCKET_TIMEOUT;  
220 - }  
221 -  
222 - return ERROR_SOCKET_WRITE;  
223 - }  
224 -  
225 - send_bytes += nb_write;  
226 -  
227 - return ret; 343 + srs_assert(io);
  344 + return srs_hijack_io_write(io, buf, size, nwrite);
228 } 345 }
229 346
230 347
@@ -32,7 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,7 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 32
33 #include <srs_protocol_io.hpp> 33 #include <srs_protocol_io.hpp>
34 #include <srs_librtmp.hpp> 34 #include <srs_librtmp.hpp>
35 - 35 +
36 /** 36 /**
37 * simple socket stream, 37 * simple socket stream,
38 * use tcp socket, sync block mode, for client like srs-librtmp. 38 * use tcp socket, sync block mode, for client like srs-librtmp.
@@ -40,11 +40,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -40,11 +40,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 class SimpleSocketStream : public ISrsProtocolReaderWriter 40 class SimpleSocketStream : public ISrsProtocolReaderWriter
41 { 41 {
42 private: 42 private:
43 - int64_t recv_timeout;  
44 - int64_t send_timeout;  
45 - int64_t recv_bytes;  
46 - int64_t send_bytes;  
47 - SOCKET fd; 43 + srs_hijack_io_t io;
48 public: 44 public:
49 SimpleSocketStream(); 45 SimpleSocketStream();
50 virtual ~SimpleSocketStream(); 46 virtual ~SimpleSocketStream();
@@ -49,7 +49,7 @@ using namespace std; @@ -49,7 +49,7 @@ using namespace std;
49 #include <srs_lib_bandwidth.hpp> 49 #include <srs_lib_bandwidth.hpp>
50 50
51 // if want to use your log, define the folowing macro. 51 // if want to use your log, define the folowing macro.
52 -#ifndef SRS_RTMP_USER_DEFINED_LOG 52 +#ifndef SRS_HIJACK_LOG
53 // kernel module. 53 // kernel module.
54 ISrsLog* _srs_log = new ISrsLog(); 54 ISrsLog* _srs_log = new ISrsLog();
55 ISrsThreadContext* _srs_context = new ISrsThreadContext(); 55 ISrsThreadContext* _srs_context = new ISrsThreadContext();
@@ -930,6 +930,93 @@ extern const char* srs_human_format_time(); @@ -930,6 +930,93 @@ extern const char* srs_human_format_time();
930 #define srs_human_verbose(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n") 930 #define srs_human_verbose(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n")
931 #define srs_human_raw(msg, ...) printf(msg, ##__VA_ARGS__) 931 #define srs_human_raw(msg, ...) printf(msg, ##__VA_ARGS__)
932 932
  933 +/*************************************************************
  934 +**************************************************************
  935 +* IO hijack, use your specified io functions.
  936 +**************************************************************
  937 +*************************************************************/
  938 +// the void* will convert to your handler for io hijack.
  939 +typedef void* srs_hijack_io_t;
  940 +// define the following macro and functions in your module to hijack the io.
  941 +// the example @see https://github.com/winlinvip/st-load
  942 +// which use librtmp but use its own io(use st also).
  943 +#ifdef SRS_HIJACK_IO
  944 + /**
  945 + * create hijack.
  946 + * @return NULL for error; otherwise, ok.
  947 + */
  948 + extern srs_hijack_io_t srs_hijack_io_create();
  949 + /**
  950 + * destroy the context, user must close the socket.
  951 + */
  952 + extern void srs_hijack_io_destroy(srs_hijack_io_t ctx);
  953 + /**
  954 + * create socket, not connect yet.
  955 + * @return 0, success; otherswise, failed.
  956 + */
  957 + extern int srs_hijack_io_create_socket(srs_hijack_io_t ctx);
  958 + /**
  959 + * connect socket at server_ip:port.
  960 + * @return 0, success; otherswise, failed.
  961 + */
  962 + extern int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port);
  963 + /**
  964 + * read from socket.
  965 + * @return 0, success; otherswise, failed.
  966 + */
  967 + extern int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread);
  968 + /**
  969 + * set the socket recv timeout.
  970 + * @return 0, success; otherswise, failed.
  971 + */
  972 + extern void srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us);
  973 + /**
  974 + * get the socket recv timeout.
  975 + * @return 0, success; otherswise, failed.
  976 + */
  977 + extern int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx);
  978 + /**
  979 + * get the socket recv bytes.
  980 + * @return 0, success; otherswise, failed.
  981 + */
  982 + extern int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx);
  983 + /**
  984 + * set the socket send timeout.
  985 + * @return 0, success; otherswise, failed.
  986 + */
  987 + extern void srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t timeout_us);
  988 + /**
  989 + * get the socket send timeout.
  990 + * @return 0, success; otherswise, failed.
  991 + */
  992 + extern int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx);
  993 + /**
  994 + * get the socket send bytes.
  995 + * @return 0, success; otherswise, failed.
  996 + */
  997 + extern int64_t srs_hijack_io_get_send_bytes(srs_hijack_io_t ctx);
  998 + /**
  999 + * writev of socket.
  1000 + * @return 0, success; otherswise, failed.
  1001 + */
  1002 + extern int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ssize_t* nwrite);
  1003 + /**
  1004 + * whether the timeout is never timeout.
  1005 + * @return 0, success; otherswise, failed.
  1006 + */
  1007 + extern bool srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t timeout_us);
  1008 + /**
  1009 + * read fully, fill the buf exactly size bytes.
  1010 + * @return 0, success; otherswise, failed.
  1011 + */
  1012 + extern int srs_hijack_io_read_fully(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread);
  1013 + /**
  1014 + * write bytes to socket.
  1015 + * @return 0, success; otherswise, failed.
  1016 + */
  1017 + extern int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite);
  1018 +#endif
  1019 +
933 #ifdef __cplusplus 1020 #ifdef __cplusplus
934 } 1021 }
935 #endif 1022 #endif