| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_framer.h" | 5 #include "net/quic/quic_framer.h" |
| 6 | 6 |
| 7 #include <cstdint> | 7 #include <cstdint> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 namespace net { | 32 namespace net { |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 // Mask to select the lowest 48 bits of a packet number. | 36 // Mask to select the lowest 48 bits of a packet number. |
| 37 const QuicPacketNumber k6ByteSequenceNumberMask = UINT64_C(0x0000FFFFFFFFFFFF); | 37 const QuicPacketNumber k6ByteSequenceNumberMask = UINT64_C(0x0000FFFFFFFFFFFF); |
| 38 const QuicPacketNumber k4ByteSequenceNumberMask = UINT64_C(0x00000000FFFFFFFF); | 38 const QuicPacketNumber k4ByteSequenceNumberMask = UINT64_C(0x00000000FFFFFFFF); |
| 39 const QuicPacketNumber k2ByteSequenceNumberMask = UINT64_C(0x000000000000FFFF); | 39 const QuicPacketNumber k2ByteSequenceNumberMask = UINT64_C(0x000000000000FFFF); |
| 40 const QuicPacketNumber k1ByteSequenceNumberMask = UINT64_C(0x00000000000000FF); | 40 const QuicPacketNumber k1ByteSequenceNumberMask = UINT64_C(0x00000000000000FF); |
| 41 | 41 |
| 42 const QuicConnectionId k1ByteConnectionIdMask = UINT64_C(0x00000000000000FF); | |
| 43 const QuicConnectionId k4ByteConnectionIdMask = UINT64_C(0x00000000FFFFFFFF); | |
| 44 | |
| 45 // Number of bits the packet number length bits are shifted from the right | 42 // Number of bits the packet number length bits are shifted from the right |
| 46 // edge of the public header. | 43 // edge of the public header. |
| 47 const uint8_t kPublicHeaderSequenceNumberShift = 4; | 44 const uint8_t kPublicHeaderSequenceNumberShift = 4; |
| 48 | 45 |
| 49 // New Frame Types, QUIC v. >= 10: | 46 // New Frame Types, QUIC v. >= 10: |
| 50 // There are two interpretations for the Frame Type byte in the QUIC protocol, | 47 // There are two interpretations for the Frame Type byte in the QUIC protocol, |
| 51 // resulting in two Frame Types: Special Frame Types and Regular Frame Types. | 48 // resulting in two Frame Types: Special Frame Types and Regular Frame Types. |
| 52 // | 49 // |
| 53 // Regular Frame Types use the Frame Type byte simply. Currently defined | 50 // Regular Frame Types use the Frame Type byte simply. Currently defined |
| 54 // Regular Frame Types are: | 51 // Regular Frame Types are: |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 public_flags |= PACKET_PUBLIC_FLAGS_VERSION; | 643 public_flags |= PACKET_PUBLIC_FLAGS_VERSION; |
| 647 } | 644 } |
| 648 if (header.public_header.multipath_flag) { | 645 if (header.public_header.multipath_flag) { |
| 649 public_flags |= PACKET_PUBLIC_FLAGS_MULTIPATH; | 646 public_flags |= PACKET_PUBLIC_FLAGS_MULTIPATH; |
| 650 } | 647 } |
| 651 | 648 |
| 652 public_flags |= | 649 public_flags |= |
| 653 GetSequenceNumberFlags(header.public_header.packet_number_length) | 650 GetSequenceNumberFlags(header.public_header.packet_number_length) |
| 654 << kPublicHeaderSequenceNumberShift; | 651 << kPublicHeaderSequenceNumberShift; |
| 655 | 652 |
| 653 if (header.public_header.nonce != nullptr) { |
| 654 DCHECK_EQ(Perspective::IS_SERVER, perspective_); |
| 655 public_flags |= PACKET_PUBLIC_FLAGS_NONCE; |
| 656 } |
| 657 |
| 656 switch (header.public_header.connection_id_length) { | 658 switch (header.public_header.connection_id_length) { |
| 657 case PACKET_0BYTE_CONNECTION_ID: | 659 case PACKET_0BYTE_CONNECTION_ID: |
| 658 if (!writer->WriteUInt8(public_flags | | 660 if (!writer->WriteUInt8(public_flags | |
| 659 PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) { | 661 PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) { |
| 660 return false; | 662 return false; |
| 661 } | 663 } |
| 662 break; | 664 break; |
| 663 case PACKET_1BYTE_CONNECTION_ID: | |
| 664 if (!writer->WriteUInt8(public_flags | | |
| 665 PACKET_PUBLIC_FLAGS_1BYTE_CONNECTION_ID)) { | |
| 666 return false; | |
| 667 } | |
| 668 if (!writer->WriteUInt8(header.public_header.connection_id & | |
| 669 k1ByteConnectionIdMask)) { | |
| 670 return false; | |
| 671 } | |
| 672 break; | |
| 673 case PACKET_4BYTE_CONNECTION_ID: | |
| 674 if (!writer->WriteUInt8(public_flags | | |
| 675 PACKET_PUBLIC_FLAGS_4BYTE_CONNECTION_ID)) { | |
| 676 return false; | |
| 677 } | |
| 678 if (!writer->WriteUInt32(header.public_header.connection_id & | |
| 679 k4ByteConnectionIdMask)) { | |
| 680 return false; | |
| 681 } | |
| 682 break; | |
| 683 case PACKET_8BYTE_CONNECTION_ID: | 665 case PACKET_8BYTE_CONNECTION_ID: |
| 684 if (!writer->WriteUInt8(public_flags | | 666 if (quic_version_ > QUIC_VERSION_32) { |
| 685 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID)) { | 667 public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID; |
| 686 return false; | 668 } else { |
| 669 public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD; |
| 687 } | 670 } |
| 688 if (!writer->WriteUInt64(header.public_header.connection_id)) { | 671 if (!writer->WriteUInt8(public_flags) || |
| 672 !writer->WriteUInt64(header.public_header.connection_id)) { |
| 689 return false; | 673 return false; |
| 690 } | 674 } |
| 691 break; | 675 break; |
| 692 } | 676 } |
| 693 last_serialized_connection_id_ = header.public_header.connection_id; | 677 last_serialized_connection_id_ = header.public_header.connection_id; |
| 694 | 678 |
| 695 if (header.public_header.version_flag) { | 679 if (header.public_header.version_flag) { |
| 696 DCHECK_EQ(Perspective::IS_CLIENT, perspective_); | 680 DCHECK_EQ(Perspective::IS_CLIENT, perspective_); |
| 697 QuicTag tag = QuicVersionToQuicTag(quic_version_); | 681 QuicTag tag = QuicVersionToQuicTag(quic_version_); |
| 698 writer->WriteUInt32(tag); | 682 writer->WriteUInt32(tag); |
| 699 DVLOG(1) << "version = " << quic_version_ << ", tag = '" | 683 DVLOG(1) << "version = " << quic_version_ << ", tag = '" |
| 700 << QuicUtils::TagToString(tag) << "'"; | 684 << QuicUtils::TagToString(tag) << "'"; |
| 701 } | 685 } |
| 702 | 686 |
| 703 if (header.public_header.multipath_flag && | 687 if (header.public_header.multipath_flag && |
| 704 !writer->WriteUInt8(header.path_id)) { | 688 !writer->WriteUInt8(header.path_id)) { |
| 705 return false; | 689 return false; |
| 706 } | 690 } |
| 707 | 691 |
| 692 if (header.public_header.nonce != nullptr && |
| 693 !writer->WriteBytes(header.public_header.nonce, |
| 694 kDiversificationNonceSize)) { |
| 695 return false; |
| 696 } |
| 697 |
| 708 if (!AppendPacketSequenceNumber(header.public_header.packet_number_length, | 698 if (!AppendPacketSequenceNumber(header.public_header.packet_number_length, |
| 709 header.packet_number, writer)) { | 699 header.packet_number, writer)) { |
| 710 return false; | 700 return false; |
| 711 } | 701 } |
| 712 | 702 |
| 713 uint8_t private_flags = 0; | 703 uint8_t private_flags = 0; |
| 714 if (header.entropy_flag) { | 704 if (header.entropy_flag) { |
| 715 private_flags |= PACKET_PRIVATE_FLAGS_ENTROPY; | 705 private_flags |= PACKET_PRIVATE_FLAGS_ENTROPY; |
| 716 } | 706 } |
| 717 if (!writer->WriteUInt8(private_flags)) { | 707 if (!writer->WriteUInt8(private_flags)) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 } | 810 } |
| 821 | 811 |
| 822 switch (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) { | 812 switch (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) { |
| 823 case PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID: | 813 case PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID: |
| 824 if (!reader->ReadUInt64(&public_header->connection_id)) { | 814 if (!reader->ReadUInt64(&public_header->connection_id)) { |
| 825 set_detailed_error("Unable to read ConnectionId."); | 815 set_detailed_error("Unable to read ConnectionId."); |
| 826 return false; | 816 return false; |
| 827 } | 817 } |
| 828 public_header->connection_id_length = PACKET_8BYTE_CONNECTION_ID; | 818 public_header->connection_id_length = PACKET_8BYTE_CONNECTION_ID; |
| 829 break; | 819 break; |
| 830 case PACKET_PUBLIC_FLAGS_4BYTE_CONNECTION_ID: | |
| 831 // If the connection_id is truncated, expect to read the last serialized | |
| 832 // connection_id. | |
| 833 if (!reader->ReadBytes(&public_header->connection_id, | |
| 834 PACKET_4BYTE_CONNECTION_ID)) { | |
| 835 set_detailed_error("Unable to read ConnectionId."); | |
| 836 return false; | |
| 837 } | |
| 838 if (last_serialized_connection_id_ && | |
| 839 (public_header->connection_id & k4ByteConnectionIdMask) != | |
| 840 (last_serialized_connection_id_ & k4ByteConnectionIdMask)) { | |
| 841 set_detailed_error( | |
| 842 "Truncated 4 byte ConnectionId does not match " | |
| 843 "previous connection_id."); | |
| 844 return false; | |
| 845 } | |
| 846 public_header->connection_id_length = PACKET_4BYTE_CONNECTION_ID; | |
| 847 public_header->connection_id = last_serialized_connection_id_; | |
| 848 break; | |
| 849 case PACKET_PUBLIC_FLAGS_1BYTE_CONNECTION_ID: | |
| 850 if (!reader->ReadBytes(&public_header->connection_id, | |
| 851 PACKET_1BYTE_CONNECTION_ID)) { | |
| 852 set_detailed_error("Unable to read ConnectionId."); | |
| 853 return false; | |
| 854 } | |
| 855 if (last_serialized_connection_id_ && | |
| 856 (public_header->connection_id & k1ByteConnectionIdMask) != | |
| 857 (last_serialized_connection_id_ & k1ByteConnectionIdMask)) { | |
| 858 set_detailed_error( | |
| 859 "Truncated 1 byte ConnectionId does not match " | |
| 860 "previous connection_id."); | |
| 861 return false; | |
| 862 } | |
| 863 public_header->connection_id_length = PACKET_1BYTE_CONNECTION_ID; | |
| 864 public_header->connection_id = last_serialized_connection_id_; | |
| 865 break; | |
| 866 case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID: | 820 case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID: |
| 867 public_header->connection_id_length = PACKET_0BYTE_CONNECTION_ID; | 821 public_header->connection_id_length = PACKET_0BYTE_CONNECTION_ID; |
| 868 public_header->connection_id = last_serialized_connection_id_; | 822 public_header->connection_id = last_serialized_connection_id_; |
| 869 break; | 823 break; |
| 870 } | 824 } |
| 871 | 825 |
| 872 public_header->packet_number_length = ReadSequenceNumberLength( | 826 public_header->packet_number_length = ReadSequenceNumberLength( |
| 873 public_flags >> kPublicHeaderSequenceNumberShift); | 827 public_flags >> kPublicHeaderSequenceNumberShift); |
| 874 | 828 |
| 875 // Read the version only if the packet is from the client. | 829 // Read the version only if the packet is from the client. |
| 876 // version flag from the server means version negotiation packet. | 830 // version flag from the server means version negotiation packet. |
| 877 if (public_header->version_flag && perspective_ == Perspective::IS_SERVER) { | 831 if (public_header->version_flag && perspective_ == Perspective::IS_SERVER) { |
| 878 QuicTag version_tag; | 832 QuicTag version_tag; |
| 879 if (!reader->ReadUInt32(&version_tag)) { | 833 if (!reader->ReadUInt32(&version_tag)) { |
| 880 set_detailed_error("Unable to read protocol version."); | 834 set_detailed_error("Unable to read protocol version."); |
| 881 return false; | 835 return false; |
| 882 } | 836 } |
| 883 | 837 |
| 884 // If the version from the new packet is the same as the version of this | 838 // If the version from the new packet is the same as the version of this |
| 885 // framer, then the public flags should be set to something we understand. | 839 // framer, then the public flags should be set to something we understand. |
| 886 // If not, this raises an error. | 840 // If not, this raises an error. |
| 887 last_version_tag_ = version_tag; | 841 last_version_tag_ = version_tag; |
| 888 QuicVersion version = QuicTagToQuicVersion(version_tag); | 842 QuicVersion version = QuicTagToQuicVersion(version_tag); |
| 889 if (version == quic_version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) { | 843 if (version == quic_version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) { |
| 890 set_detailed_error("Illegal public flags value."); | 844 set_detailed_error("Illegal public flags value."); |
| 891 return false; | 845 return false; |
| 892 } | 846 } |
| 893 public_header->versions.push_back(version); | 847 public_header->versions.push_back(version); |
| 894 } | 848 } |
| 849 |
| 850 // A nonce should only be present in packets from the server to the client, |
| 851 // and only for versions after QUIC_VERSION_32. Earlier versions will |
| 852 // set this bit when indicating an 8-byte connection ID, which should |
| 853 // not be interpreted as indicating a nonce is present. |
| 854 if (quic_version_ > QUIC_VERSION_32 && |
| 855 public_flags & PACKET_PUBLIC_FLAGS_NONCE && |
| 856 // The nonce flag from a client is ignored and is assumed to be an older |
| 857 // client indicating an eight-byte connection ID. |
| 858 perspective_ == Perspective::IS_CLIENT) { |
| 859 if (!reader->ReadBytes(reinterpret_cast<uint8_t*>(last_nonce_), |
| 860 sizeof(last_nonce_))) { |
| 861 set_detailed_error("Unable to read nonce."); |
| 862 return false; |
| 863 } |
| 864 public_header->nonce = &last_nonce_; |
| 865 } else { |
| 866 public_header->nonce = nullptr; |
| 867 } |
| 868 |
| 895 return true; | 869 return true; |
| 896 } | 870 } |
| 897 | 871 |
| 898 // static | 872 // static |
| 899 QuicPacketNumberLength QuicFramer::GetMinSequenceNumberLength( | 873 QuicPacketNumberLength QuicFramer::GetMinSequenceNumberLength( |
| 900 QuicPacketNumber packet_number) { | 874 QuicPacketNumber packet_number) { |
| 901 if (packet_number < 1 << (PACKET_1BYTE_PACKET_NUMBER * 8)) { | 875 if (packet_number < 1 << (PACKET_1BYTE_PACKET_NUMBER * 8)) { |
| 902 return PACKET_1BYTE_PACKET_NUMBER; | 876 return PACKET_1BYTE_PACKET_NUMBER; |
| 903 } else if (packet_number < 1 << (PACKET_2BYTE_PACKET_NUMBER * 8)) { | 877 } else if (packet_number < 1 << (PACKET_2BYTE_PACKET_NUMBER * 8)) { |
| 904 return PACKET_2BYTE_PACKET_NUMBER; | 878 return PACKET_2BYTE_PACKET_NUMBER; |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 | 1582 |
| 1609 return true; | 1583 return true; |
| 1610 } | 1584 } |
| 1611 | 1585 |
| 1612 // static | 1586 // static |
| 1613 StringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket( | 1587 StringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket( |
| 1614 const QuicEncryptedPacket& encrypted, | 1588 const QuicEncryptedPacket& encrypted, |
| 1615 QuicConnectionIdLength connection_id_length, | 1589 QuicConnectionIdLength connection_id_length, |
| 1616 bool includes_version, | 1590 bool includes_version, |
| 1617 bool includes_path_id, | 1591 bool includes_path_id, |
| 1592 bool includes_diversification_nonce, |
| 1618 QuicPacketNumberLength packet_number_length) { | 1593 QuicPacketNumberLength packet_number_length) { |
| 1619 // TODO(ianswett): This is identical to QuicData::AssociatedData. | 1594 // TODO(ianswett): This is identical to QuicData::AssociatedData. |
| 1620 return StringPiece( | 1595 return StringPiece( |
| 1621 encrypted.data(), | 1596 encrypted.data(), |
| 1622 GetStartOfEncryptedData(connection_id_length, includes_version, | 1597 GetStartOfEncryptedData(connection_id_length, includes_version, |
| 1623 includes_path_id, packet_number_length)); | 1598 includes_path_id, includes_diversification_nonce, |
| 1599 packet_number_length)); |
| 1624 } | 1600 } |
| 1625 | 1601 |
| 1626 void QuicFramer::SetDecrypter(EncryptionLevel level, QuicDecrypter* decrypter) { | 1602 void QuicFramer::SetDecrypter(EncryptionLevel level, QuicDecrypter* decrypter) { |
| 1627 DCHECK(alternative_decrypter_.get() == nullptr); | 1603 DCHECK(alternative_decrypter_.get() == nullptr); |
| 1628 DCHECK_GE(level, decrypter_level_); | 1604 DCHECK_GE(level, decrypter_level_); |
| 1629 decrypter_.reset(decrypter); | 1605 decrypter_.reset(decrypter); |
| 1630 decrypter_level_ = level; | 1606 decrypter_level_ = level; |
| 1631 } | 1607 } |
| 1632 | 1608 |
| 1633 void QuicFramer::SetAlternativeDecrypter(EncryptionLevel level, | 1609 void QuicFramer::SetAlternativeDecrypter(EncryptionLevel level, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1719 const QuicPacketHeader& header, | 1695 const QuicPacketHeader& header, |
| 1720 const QuicEncryptedPacket& packet, | 1696 const QuicEncryptedPacket& packet, |
| 1721 char* decrypted_buffer, | 1697 char* decrypted_buffer, |
| 1722 size_t buffer_length, | 1698 size_t buffer_length, |
| 1723 size_t* decrypted_length) { | 1699 size_t* decrypted_length) { |
| 1724 StringPiece encrypted = encrypted_reader->ReadRemainingPayload(); | 1700 StringPiece encrypted = encrypted_reader->ReadRemainingPayload(); |
| 1725 DCHECK(decrypter_.get() != nullptr); | 1701 DCHECK(decrypter_.get() != nullptr); |
| 1726 StringPiece associated_data = GetAssociatedDataFromEncryptedPacket( | 1702 StringPiece associated_data = GetAssociatedDataFromEncryptedPacket( |
| 1727 packet, header.public_header.connection_id_length, | 1703 packet, header.public_header.connection_id_length, |
| 1728 header.public_header.version_flag, header.public_header.multipath_flag, | 1704 header.public_header.version_flag, header.public_header.multipath_flag, |
| 1705 header.public_header.nonce != nullptr, |
| 1729 header.public_header.packet_number_length); | 1706 header.public_header.packet_number_length); |
| 1707 |
| 1730 bool success = decrypter_->DecryptPacket( | 1708 bool success = decrypter_->DecryptPacket( |
| 1731 header.path_id, header.packet_number, associated_data, encrypted, | 1709 header.path_id, header.packet_number, associated_data, encrypted, |
| 1732 decrypted_buffer, decrypted_length, buffer_length); | 1710 decrypted_buffer, decrypted_length, buffer_length); |
| 1733 if (success) { | 1711 if (success) { |
| 1734 visitor_->OnDecryptedPacket(decrypter_level_); | 1712 visitor_->OnDecryptedPacket(decrypter_level_); |
| 1735 } else if (alternative_decrypter_.get() != nullptr) { | 1713 } else if (alternative_decrypter_.get() != nullptr) { |
| 1714 if (header.public_header.nonce != nullptr) { |
| 1715 DCHECK_EQ(perspective_, Perspective::IS_CLIENT); |
| 1716 alternative_decrypter_->SetDiversificationNonce( |
| 1717 *header.public_header.nonce); |
| 1718 } |
| 1719 if (alternative_decrypter_level_ == ENCRYPTION_INITIAL) { |
| 1720 if (perspective_ == Perspective::IS_CLIENT && |
| 1721 quic_version_ > QUIC_VERSION_32) { |
| 1722 DCHECK(header.public_header.nonce != nullptr); |
| 1723 } else { |
| 1724 DCHECK(header.public_header.nonce == nullptr); |
| 1725 } |
| 1726 } |
| 1727 |
| 1736 success = alternative_decrypter_->DecryptPacket( | 1728 success = alternative_decrypter_->DecryptPacket( |
| 1737 header.path_id, header.packet_number, associated_data, encrypted, | 1729 header.path_id, header.packet_number, associated_data, encrypted, |
| 1738 decrypted_buffer, decrypted_length, buffer_length); | 1730 decrypted_buffer, decrypted_length, buffer_length); |
| 1739 if (success) { | 1731 if (success) { |
| 1740 visitor_->OnDecryptedPacket(alternative_decrypter_level_); | 1732 visitor_->OnDecryptedPacket(alternative_decrypter_level_); |
| 1741 if (alternative_decrypter_latch_) { | 1733 if (alternative_decrypter_latch_) { |
| 1742 // Switch to the alternative decrypter and latch so that we cannot | 1734 // Switch to the alternative decrypter and latch so that we cannot |
| 1743 // switch back. | 1735 // switch back. |
| 1744 decrypter_.reset(alternative_decrypter_.release()); | 1736 decrypter_.reset(alternative_decrypter_.release()); |
| 1745 decrypter_level_ = alternative_decrypter_level_; | 1737 decrypter_level_ = alternative_decrypter_level_; |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2257 | 2249 |
| 2258 bool QuicFramer::RaiseError(QuicErrorCode error) { | 2250 bool QuicFramer::RaiseError(QuicErrorCode error) { |
| 2259 DVLOG(1) << "Error: " << QuicUtils::ErrorToString(error) | 2251 DVLOG(1) << "Error: " << QuicUtils::ErrorToString(error) |
| 2260 << " detail: " << detailed_error_; | 2252 << " detail: " << detailed_error_; |
| 2261 set_error(error); | 2253 set_error(error); |
| 2262 visitor_->OnError(this); | 2254 visitor_->OnError(this); |
| 2263 return false; | 2255 return false; |
| 2264 } | 2256 } |
| 2265 | 2257 |
| 2266 } // namespace net | 2258 } // namespace net |
| OLD | NEW |