nginx rtmp handshake过程
接收到rtmp流,执行流程
17 void
18 ngx_rtmp_init_connection(ngx_connection_t *c)
19 {
20 ngx_uint_t i;
21 ngx_rtmp_port_t *port;
22 struct sockaddr *sa;
23 struct sockaddr_in *sin;
24 ngx_rtmp_in_addr_t *addr;
25 ngx_rtmp_session_t *s;
26 ngx_rtmp_addr_conf_t *addr_conf;
27 ngx_int_t unix_socket;
28 #if (NGX_HAVE_INET6)
29 struct sockaddr_in6 *sin6;
30 ngx_rtmp_in6_addr_t *addr6;
31 #endif
32
33 ++ngx_rtmp_naccepted
... ...
124 s = ngx_rtmp_init_session(c, addr_conf);
125 if (s == NULL) {
126 return;
127 }
128
(gdb)
129 /* only auto-pushed connections are
130 * done through unix socket */
131
132 s->auto_pushed = unix_socket;
133 if(s->auto_pushed){
134 s->addr_text = &null_addr_text;
135 }
136
137 if (addr_conf->proxy_protocol) {
138 ngx_rtmp_proxy_protocol(s);
(gdb)
139
140 } else {
141 ngx_rtmp_handshake(s);
142 }
143 }
(gdb) bt
#0 ngx_rtmp_init_connection (c=0x7fffd7afd2f8) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_init.c:33
#1 0x000000000047596f in ngx_event_accept (ev=0x7fffd79f8078) at src/event/ngx_event_accept.c:359
#2 0x00000000004824a8 in ngx_epoll_process_events (cycle=0x20d0030, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:691
#3 0x0000000000471bf8 in ngx_process_events_and_timers (cycle=0x20d0030) at src/event/ngx_event.c:248
#4 0x000000000047eb1c in ngx_single_process_cycle (cycle=0x20d0030) at src/os/unix/ngx_process_cycle.c:317
#5 0x000000000044a19e in main (argc=3, argv=0x7fffffffe518) at src/core/nginx.c:411
初始化session
83 ngx_rtmp_limit_connect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
84 ngx_chain_t *in)
(gdb) bt
#0 ngx_rtmp_limit_connect (s=0x2211b50, h=0x0, in=0x0) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_limit_module.c:92
#1 0x00000000005448c8 in ngx_rtmp_fire_event (s=0x2211b50, evt=23, h=0x0, in=0x0) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp.c:855
#2 0x0000000000545eea in ngx_rtmp_init_session (c=0x7fffd7d6d2f8, addr_conf=0x2202410) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_init.c:234
#3 0x0000000000545a1a in ngx_rtmp_init_connection (c=0x7fffd7d6d2f8) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_init.c:124
#4 0x00000000004735b8 in ngx_event_accept (ev=0x7fffd7c68078) at src/event/ngx_event_accept.c:359
#5 0x000000000047de6e in ngx_epoll_process_events (cycle=0x2101010, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:691
#6 0x00000000004704ce in ngx_process_events_and_timers (cycle=0x2101010) at src/event/ngx_event.c:248
#7 0x000000000047ae50 in ngx_single_process_cycle (cycle=0x2101010) at src/os/unix/ngx_process_cycle.c:317
#8 0x000000000044ab1e in main (argc=3, argv=0x7fffffffe548) at src/core/nginx.c:411
ngx_rtmp_limit_connect()
ngx_rtmp_fire_event() //(*hh)(s, h, in)回调函数ngx_rtmp_limit_connect()
ngx_rtmp_init_session()
ngx_rtmp_init_connection()
ngx_event_accept() // ls->handler(c);回调函数ngx_rtmp_init_connection()
ngx_epoll_process_events() //rev->handler(rev);回调函数ngx_event_accept()
ngx_process_events_and_timers()//(void) ngx_process_events(cycle, timer, flags);回调函数ngx_epoll_process_events()
握手handshake
593 ngx_rtmp_handshake_recv(c->read);
(gdb) bt
#0 ngx_rtmp_handshake (s=0x2211b50) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:593
#1 0x0000000000545a93 in ngx_rtmp_init_connection (c=0x7fffd7d6d2f8) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_init.c:141
#2 0x00000000004735b8 in ngx_event_accept (ev=0x7fffd7c68078) at src/event/ngx_event_accept.c:359
#3 0x000000000047de6e in ngx_epoll_process_events (cycle=0x2101010, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:691
#4 0x00000000004704ce in ngx_process_events_and_timers (cycle=0x2101010) at src/event/ngx_event.c:248
#5 0x000000000047ae50 in ngx_single_process_cycle (cycle=0x2101010) at src/os/unix/ngx_process_cycle.c:317
#6 0x000000000044ab1e in main (argc=3, argv=0x7fffffffe548) at src/core/nginx.c:411
其中:
c->read->handler = ngx_rtmp_handshake_recv;
c->write->handler = ngx_rtmp_handshake_send;
rtmp利用状态机来实现握手的动作。
状态一: NGX_RTMP_HANDSHAKE_SERVER_RECV_CHALLENGE
398 while (b->last != b->end) {
(gdb)
399 n = c->recv(c, b->last, b->end - b->last);
(gdb) p b->end - b->last
$6 = 1537
(gdb) bt
#0 ngx_rtmp_handshake_recv (rev=0x7fffd7c68148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:377
#1 0x0000000000547918 in ngx_rtmp_handshake (s=0x2211b50) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:593
#2 0x0000000000545a93 in ngx_rtmp_init_connection (c=0x7fffd7d6d2f8) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_init.c:141
#3 0x00000000004735b8 in ngx_event_accept (ev=0x7fffd7c68078) at src/event/ngx_event_accept.c:359
#4 0x000000000047de6e in ngx_epoll_process_events (cycle=0x2101010, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:691
#5 0x00000000004704ce in ngx_process_events_and_timers (cycle=0x2101010) at src/event/ngx_event.c:248
#6 0x000000000047ae50 in ngx_single_process_cycle (cycle=0x2101010) at src/os/unix/ngx_process_cycle.c:317
#7 0x000000000044ab1e in main (argc=3, argv=0x7fffffffe548) at src/core/nginx.c:411
其中这是握手的第一个状态:s->hs_stage = NGX_RTMP_HANDSHAKE_SERVER_RECV_CHALLENGE;
调用函数ngx_rtmp_handshake_recv(c->read);执行 c->recv(c, b->last, b->end - b->last),接收1537字节的C0+C1数据。
状态二:NGX_RTMP_HANDSHAKE_SERVER_SEND_CHALLENGE
518 while(b->pos != b->last) {
(gdb)
519 n = c->send(c, b->pos, b->last - b->pos);
(gdb) p b->last - b->pos
$11 = 1537
(gdb) bt
#0 ngx_rtmp_handshake_send (wev=0x7fffd7b63148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:519
#1 0x0000000000547364 in ngx_rtmp_handshake_recv (rev=0x7fffd7c68148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:450
#2 0x0000000000547918 in ngx_rtmp_handshake (s=0x2211b50) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:593
#3 0x0000000000545a93 in ngx_rtmp_init_connection (c=0x7fffd7d6d2f8) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_init.c:141
#4 0x00000000004735b8 in ngx_event_accept (ev=0x7fffd7c68078) at src/event/ngx_event_accept.c:359
#5 0x000000000047de6e in ngx_epoll_process_events (cycle=0x2101010, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:691
#6 0x00000000004704ce in ngx_process_events_and_timers (cycle=0x2101010) at src/event/ngx_event.c:248
#7 0x000000000047ae50 in ngx_single_process_cycle (cycle=0x2101010) at src/os/unix/ngx_process_cycle.c:317
#8 0x000000000044ab1e in main (argc=3, argv=0x7fffffffe548) at src/core/nginx.c:411
握手的第二个状态为:NGX_RTMP_HANDSHAKE_SERVER_SEND_CHALLENGE
调用函数ngx_rtmp_handshake_send(c->write);执行c->send(c, b->pos, b->last - b->pos);向客户端发送1537字节的S0+S1数据
状态三:NGX_RTMP_HANDSHAKE_SERVER_SEND_RESPONSE
调用函数ngx_rtmp_handshake_send(c->write);执行c->send(c, b->pos, b->last - b->pos);向客户端发送1536字节的S2数据
状态四:NGX_RTMP_HANDSHAKE_SERVER_RECV_RESPONSE
调用函数ngx_rtmp_handshake_recv(c->read);执行 c->recv(c, b->last, b->end - b->last),接收1536字节的C2数据。
服务器端握手过程:
接收C0,C1 ---> 发送S0,S1 ---> 发送S2 ---> 接收C2
状态五:NGX_RTMP_HANDSHAKE_SERVER_DONE
调用函数ngx_rtmp_handshake_done(s);握手结束。
350 static void
351 ngx_rtmp_handshake_done(ngx_rtmp_session_t *s)
352 {
353 ngx_rtmp_free_handshake_buffers(s);
354
355 ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
356 "handshake: done");
358 if (ngx_rtmp_fire_event(s, NGX_RTMP_HANDSHAKE_DONE,
(gdb) bt
#0 ngx_rtmp_handshake_done (s=0x2211b50) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:358
#1 0x0000000000547375 in ngx_rtmp_handshake_recv (rev=0x7fffd7c68148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:454
#2 0x000000000054784a in ngx_rtmp_handshake_send (wev=0x7fffd7b63148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:563
#3 0x0000000000547801 in ngx_rtmp_handshake_send (wev=0x7fffd7b63148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:558
#4 0x0000000000547364 in ngx_rtmp_handshake_recv (rev=0x7fffd7c68148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:450
#5 0x0000000000547918 in ngx_rtmp_handshake (s=0x2211b50) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:593
#6 0x0000000000545a93 in ngx_rtmp_init_connection (c=0x7fffd7d6d2f8) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_init.c:141
#7 0x00000000004735b8 in ngx_event_accept (ev=0x7fffd7c68078) at src/event/ngx_event_accept.c:359
#8 0x000000000047de6e in ngx_epoll_process_events (cycle=0x2101010, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:691
#9 0x00000000004704ce in ngx_process_events_and_timers (cycle=0x2101010) at src/event/ngx_event.c:248
#10 0x000000000047ae50 in ngx_single_process_cycle (cycle=0x2101010) at src/os/unix/ngx_process_cycle.c:317
#11 0x000000000044ab1e in main (argc=3, argv=0x7fffffffe548) at src/core/nginx.c:411
ngx_rtmp_fire_event(s, NGX_RTMP_HANDSHAKE_DONE,NULL, NULL) != NGX_OK)中(*hh)(s, h, in)回调函数ngx_rtmp_relay_handshake_done()
3798 static ngx_int_t
3799 ngx_rtmp_relay_handshake_done(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
3800 ngx_chain_t *in)
3801 {
3802 ngx_rtmp_relay_ctx_t *ctx;
3803
3804 ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
3805 if (ctx == NULL || !s->relay) {
3806 return NGX_OK;
3807 }
3808
3809 return ngx_rtmp_relay_send_connect(s);
3810 }
3811
3812
3813 static void
(gdb) bt
#0 ngx_rtmp_relay_handshake_done (s=0x2211b50, h=0x0, in=0x0) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_relay_module.c:3804
#1 0x00000000005448c8 in ngx_rtmp_fire_event (s=0x2211b50, evt=25, h=0x0, in=0x0) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp.c:855
#2 0x0000000000546fca in ngx_rtmp_handshake_done (s=0x2211b50) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:358
#3 0x0000000000547375 in ngx_rtmp_handshake_recv (rev=0x7fffd7c68148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:454
#4 0x000000000054784a in ngx_rtmp_handshake_send (wev=0x7fffd7b63148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:563
#5 0x0000000000547801 in ngx_rtmp_handshake_send (wev=0x7fffd7b63148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:558
#6 0x0000000000547364 in ngx_rtmp_handshake_recv (rev=0x7fffd7c68148) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:450
#7 0x0000000000547918 in ngx_rtmp_handshake (s=0x2211b50) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_handshake.c:593
#8 0x0000000000545a93 in ngx_rtmp_init_connection (c=0x7fffd7d6d2f8) at ../../NGINX-RTMP/nginx-rtmp-module-master/ngx_rtmp_init.c:141
#9 0x00000000004735b8 in ngx_event_accept (ev=0x7fffd7c68078) at src/event/ngx_event_accept.c:359
#10 0x000000000047de6e in ngx_epoll_process_events (cycle=0x2101010, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:691
#11 0x00000000004704ce in ngx_process_events_and_timers (cycle=0x2101010) at src/event/ngx_event.c:248
#12 0x000000000047ae50 in ngx_single_process_cycle (cycle=0x2101010) at src/os/unix/ngx_process_cycle.c:317
#13 0x000000000044ab1e in main (argc=3, argv=0x7fffffffe548) at src/core/nginx.c:411
因为ctx为null,所以返回NGX_OK。
3806 return NGX_OK;
(gdb) p ctx
$11 = (ngx_rtmp_relay_ctx_t *) 0x0
接着执行ngx_rtmp_handshake_done()中的函数ngx_rtmp_cycle(s);
87 void
88 ngx_rtmp_cycle(ngx_rtmp_session_t *s)
89 {
90 ngx_connection_t *c;
91
92 c = s->connection;
93 c->read->handler = ngx_rtmp_recv;
94 c->write->handler = ngx_rtmp_send;
95
96 s->ping_evt.data = c;
97 s->ping_evt.log = c->log;
98 s->ping_evt.handler = ngx_rtmp_ping;
99 ngx_rtmp_reset_ping(s);
100
101 ngx_rtmp_recv(c->read);
102 }