| 152 | namespace policy { |
| 153 | |
| 154 | ParseResult ParseNsheadMessage(butil::IOBuf* source, |
| 155 | Socket*, bool /*read_eof*/, const void* /*arg*/) { |
| 156 | char header_buf[sizeof(nshead_t)]; |
| 157 | const size_t n = source->copy_to(header_buf, sizeof(header_buf)); |
| 158 | if (n < offsetof(nshead_t, magic_num) + 4) { |
| 159 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 160 | } |
| 161 | const void* dummy = header_buf + offsetof(nshead_t, magic_num); |
| 162 | const unsigned int magic_num = *(unsigned int*)dummy; |
| 163 | if (magic_num != NSHEAD_MAGICNUM) { |
| 164 | RPC_VLOG << "magic_num=" << magic_num |
| 165 | << " doesn't match NSHEAD_MAGICNUM=" << NSHEAD_MAGICNUM; |
| 166 | return MakeParseError(PARSE_ERROR_TRY_OTHERS); |
| 167 | } |
| 168 | if (n < sizeof(nshead_t)) { |
| 169 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 170 | } |
| 171 | const nshead_t* nshead = (const nshead_t *)header_buf; |
| 172 | uint32_t body_len = nshead->body_len; |
| 173 | if (body_len > FLAGS_max_body_size) { |
| 174 | return MakeParseError(PARSE_ERROR_TOO_BIG_DATA); |
| 175 | } else if (source->length() < sizeof(header_buf) + body_len) { |
| 176 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 177 | } |
| 178 | |
| 179 | policy::MostCommonMessage* msg = policy::MostCommonMessage::Get(); |
| 180 | source->cutn(&msg->meta, sizeof(header_buf)); |
| 181 | source->cutn(&msg->payload, body_len); |
| 182 | return MakeMessage(msg); |
| 183 | } |
| 184 | |
| 185 | namespace { |
| 186 | struct CallMethodInBackupThreadArgs { |