Returns payload size, sets inmask, is_binframe */
| 237 | |
| 238 | /* Returns payload size, sets inmask, is_binframe */ |
| 239 | static size_t read_payload_header(int fd, u8 inmask[4], bool *is_binframe) |
| 240 | { |
| 241 | /* Worst case header. */ |
| 242 | u8 frame_hdr[20]; |
| 243 | bool mask_set; |
| 244 | size_t hdrsize = 2, len; |
| 245 | |
| 246 | /* First two bytes define hdr size. */ |
| 247 | if (!read_all(fd, frame_hdr, 2)) |
| 248 | exit(0); |
| 249 | |
| 250 | /* RFC-6455: |
| 251 | * %x2 denotes a binary frame |
| 252 | */ |
| 253 | *is_binframe = ((frame_hdr[0] & 0x0F) == 2); |
| 254 | mask_set = (frame_hdr[1] & 0x80); |
| 255 | len = (frame_hdr[1] & 0x7f); |
| 256 | |
| 257 | if (len == 126) |
| 258 | hdrsize += 2; |
| 259 | else if (len == 127) |
| 260 | hdrsize += 8; |
| 261 | |
| 262 | if (mask_set) |
| 263 | hdrsize += 4; |
| 264 | |
| 265 | /* Read rest of hdr if necessary */ |
| 266 | if (hdrsize > 2 && !read_all(fd, frame_hdr + 2, hdrsize - 2)) |
| 267 | exit(0); |
| 268 | |
| 269 | if (len == 126) { |
| 270 | be16 be16len; |
| 271 | memcpy(&be16len, frame_hdr + 2, 2); |
| 272 | len = be16_to_cpu(be16len); |
| 273 | } else if (len == 127) { |
| 274 | be64 be64len; |
| 275 | memcpy(&be64len, frame_hdr + 2, 8); |
| 276 | len = be64_to_cpu(be64len); |
| 277 | } |
| 278 | |
| 279 | if (mask_set) { |
| 280 | memcpy(inmask, frame_hdr + hdrsize - 4, 4); |
| 281 | hdrsize += 4; |
| 282 | } else |
| 283 | memset(inmask, 0, 4); |
| 284 | |
| 285 | return len; |
| 286 | } |
| 287 | |
| 288 | static void apply_mask(u8 *buf, size_t len, const u8 inmask[4]) |
| 289 | { |
no test coverage detected