Mercurial > hg > nginx
comparison src/http/ngx_http_spdy.c @ 5643:436f3605195a
SPDY: consistently handle control frames with unknown type.
The SPDY draft 2 specification requires that if an endpoint receives a
control frame for a type it does not recognize, it must ignore the frame.
But the 3 and 3.1 drafts don't seem to declare any behavior for such case.
Then sticking with the previous draft in this matter looks to be right.
But previously, only 8 least significant bits of the type field were
parsed while the rest of 16 bits of the field were checked against zero.
Though there are no known frame types bigger than 255, this resulted in
inconsistency in handling of such frames: they were not recognized as
valid frames at all, and the connection was closed.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Mon, 07 Apr 2014 19:27:56 +0400 |
parents | d2ac5cf4056d |
children | e1dcb983d6b3 |
comparison
equal
deleted
inserted
replaced
5642:d2ac5cf4056d | 5643:436f3605195a |
---|---|
45 #define ngx_spdy_frame_parse_delta(p) \ | 45 #define ngx_spdy_frame_parse_delta(p) \ |
46 (ngx_spdy_frame_parse_uint32(p) & 0x7fffffff) | 46 (ngx_spdy_frame_parse_uint32(p) & 0x7fffffff) |
47 | 47 |
48 | 48 |
49 #define ngx_spdy_ctl_frame_check(h) \ | 49 #define ngx_spdy_ctl_frame_check(h) \ |
50 (((h) & 0xffffff00) == ngx_spdy_ctl_frame_head(0)) | 50 (((h) & 0xffff0000) == ngx_spdy_ctl_frame_head(0)) |
51 #define ngx_spdy_data_frame_check(h) \ | 51 #define ngx_spdy_data_frame_check(h) \ |
52 (!((h) & (uint32_t) NGX_SPDY_CTL_BIT << 31)) | 52 (!((h) & (uint32_t) NGX_SPDY_CTL_BIT << 31)) |
53 | 53 |
54 #define ngx_spdy_ctl_frame_type(h) ((h) & 0x000000ff) | 54 #define ngx_spdy_ctl_frame_type(h) ((h) & 0x0000ffff) |
55 #define ngx_spdy_frame_flags(p) ((p) >> 24) | 55 #define ngx_spdy_frame_flags(p) ((p) >> 24) |
56 #define ngx_spdy_frame_length(p) ((p) & 0x00ffffff) | 56 #define ngx_spdy_frame_length(p) ((p) & 0x00ffffff) |
57 #define ngx_spdy_frame_id(p) ((p) & 0x00ffffff) | 57 #define ngx_spdy_frame_id(p) ((p) & 0x00ffffff) |
58 | 58 |
59 | 59 |
834 | 834 |
835 static u_char * | 835 static u_char * |
836 ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos, | 836 ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos, |
837 u_char *end) | 837 u_char *end) |
838 { | 838 { |
839 uint32_t head, flen; | 839 uint32_t head, flen; |
840 ngx_uint_t type; | |
840 | 841 |
841 if (end - pos < NGX_SPDY_FRAME_HEADER_SIZE) { | 842 if (end - pos < NGX_SPDY_FRAME_HEADER_SIZE) { |
842 return ngx_http_spdy_state_save(sc, pos, end, | 843 return ngx_http_spdy_state_save(sc, pos, end, |
843 ngx_http_spdy_state_head); | 844 ngx_http_spdy_state_head); |
844 } | 845 } |
857 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, | 858 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, |
858 "spdy process frame head:%08XD f:%Xd l:%uz", | 859 "spdy process frame head:%08XD f:%Xd l:%uz", |
859 head, sc->flags, sc->length); | 860 head, sc->flags, sc->length); |
860 | 861 |
861 if (ngx_spdy_ctl_frame_check(head)) { | 862 if (ngx_spdy_ctl_frame_check(head)) { |
862 switch (ngx_spdy_ctl_frame_type(head)) { | 863 type = ngx_spdy_ctl_frame_type(head); |
864 | |
865 switch (type) { | |
863 | 866 |
864 case NGX_SPDY_SYN_STREAM: | 867 case NGX_SPDY_SYN_STREAM: |
865 return ngx_http_spdy_state_syn_stream(sc, pos, end); | 868 return ngx_http_spdy_state_syn_stream(sc, pos, end); |
866 | 869 |
867 case NGX_SPDY_SYN_REPLY: | 870 case NGX_SPDY_SYN_REPLY: |
883 return ngx_http_spdy_state_protocol_error(sc); | 886 return ngx_http_spdy_state_protocol_error(sc); |
884 | 887 |
885 case NGX_SPDY_WINDOW_UPDATE: | 888 case NGX_SPDY_WINDOW_UPDATE: |
886 return ngx_http_spdy_state_window_update(sc, pos, end); | 889 return ngx_http_spdy_state_window_update(sc, pos, end); |
887 | 890 |
888 default: /* TODO logging */ | 891 default: |
892 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, | |
893 "spdy control frame with unknown type %ui", type); | |
889 return ngx_http_spdy_state_skip(sc, pos, end); | 894 return ngx_http_spdy_state_skip(sc, pos, end); |
890 } | 895 } |
891 } | 896 } |
892 | 897 |
893 if (ngx_spdy_data_frame_check(head)) { | 898 if (ngx_spdy_data_frame_check(head)) { |