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