scenarii

package
v0.0.0-...-514d240 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2018 License: AGPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Maxime Piraux's master's thesis
    Copyright (C) 2017-2018  Maxime Piraux

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
	as published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Index

Constants

View Source
const (
	AE_TLSHandshakeFailed = 1
	AE_FailedToSetECN     = 2
	AE_NonECN             = 3
	AE_NoACKECNReceived   = 4
	AE_NonECNButACKECN    = 5
)
View Source
const (
	AO_TLSHandshakeFailed   = 1
	AO_SentAOInResponseOfAO = 2
)
View Source
const (
	AV_TLSHandshakeFailed     = 1
	AV_SentMoreThan3Datagrams = 2
)
View Source
const (
	CM_TLSHandshakeFailed        = 1
	CM_UDPConnectionFailed       = 2
	CM_HostDidNotMigrate         = 3
	CM_HostDidNotValidateNewPath = 4
)
View Source
const (
	FC_TLSHandshakeFailed          = 1
	FC_HostSentMoreThanLimit       = 2
	FC_HostDidNotResumeSending     = 3
	FC_NotEnoughDataAvailable      = 4
	FC_RespectedLimitsButNoBlocked = 5 // After discussing w/ the implementers, it is not reasonable to expect a STREAM_BLOCKED or a BLOCKED frame to be sent.

)
View Source
const (
	H_ReceivedUnexpectedPacketType = 1
	H_TLSHandshakeFailed           = 2
	H_NoCompatibleVersionAvailable = 3
	H_Timeout                      = 4
)
View Source
const (
	HR_DidNotRetransmitHandshake   = 1
	HR_VNDidNotComplete            = 2
	HR_TLSHandshakeFailed          = 3
	HR_NoPathChallengeReceived     = 4
	HR_NoPathChallengeInAllPackets = 5
	HR_NoPathChallengeConfirmation = 6
)
View Source
const (
	SGW_TLSHandshakeFailed              = 1
	SGW_EmptyStreamFrameNoFinBit        = 2
	SGW_RetransmittedAck                = 3 // This could affect performance, but we don't check it anymore
	SGW_WrongStreamIDReceived           = 4
	SGW_UnknownError                    = 5
	SGW_DidNotCloseTheConnection        = 6
	SGW_MultipleErrors                  = 7
	SGW_TooLowStreamIdBidiToSendRequest = 8
	SGW_DidntReceiveTheRequestedData    = 9
	SGW_AnsweredOnUnannouncedStream     = 10
)
View Source
const (
	GS2_TLSHandshakeFailed                    = 1
	GS2_TooLowStreamIdUniToSendRequest        = 2
	GS2_ReceivedDataOnStream2                 = 3
	GS2_ReceivedDataOnUnauthorizedStream      = 4
	GS2_AnswersToARequestOnAForbiddenStreamID = 5 // This is hard to disambiguate sometimes, we don't check anymore
	GS2_DidNotCloseTheConnection              = 6
)
View Source
const (
	MS_TLSHandshakeFailed      = 1
	MS_NoTPReceived            = 2 // We don't distinguish the two first cases anymore
	MS_NotAllStreamsWereClosed = 3
)
View Source
const (
	NCI_TLSHandshakeFailed       = 1
	NCI_HostDidNotProvideCID     = 2
	NCI_HostDidNotAnswerToNewCID = 3
	NCI_HostDidNotAdaptCID       = 4
	NCI_HostSentInvalidCIDLength = 5
)
View Source
const (
	P_VNDidNotComplete = 1
	P_ReceivedSmth     = 2
)
View Source
const (
	SSRS_TLSHandshakeFailed               = 1
	SSRS_DidNotCloseTheConnection         = 2
	SSRS_CloseTheConnectionWithWrongError = 3
	SSRS_MaxStreamUniTooLow               = 4
	SSRS_UnknownError                     = 5
)
View Source
const (
	SOR_TLSHandshakeFailed = 1
	SOR_HostDidNotRespond  = 2
)
View Source
const (
	TP_NoTPReceived            = 1
	TP_TPResentAfterVN         = 2 // All others error code are now handled by the handshake scenario
	TP_HandshakeDidNotComplete = 3
	TP_MissingParameters       = 4
)
View Source
const (
	UTS_NoConnectionCloseSent        = 1
	UTS_WrongErrorCodeIsUsed         = 2 // See https://tools.ietf.org/html/draft-ietf-quic-tls-10#section-11
	UTS_VNDidNotComplete             = 3
	UTS_ReceivedUnexpectedPacketType = 4
)
View Source
const (
	VN_NotAnsweringToVN               = 1
	VN_DidNotEchoVersion              = 2 // draft-07 and below were stating that VN packets should echo the version of the client. It is not used anymore
	VN_LastTwoVersionsAreActuallySeal = 3 // draft-05 and below used AEAD to seal cleartext packets, VN packets should not be sealed, but some implementations did anyway.
	VN_Timeout                        = 4
	VN_UnusedFieldIsIdentical         = 5 // See https://github.com/quicwg/base-drafts/issues/963
)
View Source
const (
	ZR_TLSHandshakeFailed           = 1
	ZR_NoResumptionSecret           = 2
	ZR_ZeroRTTFailed                = 3
	ZR_DidntReceiveTheRequestedData = 4
)
View Source
const ForceVersionNegotiation = 0x1a2a3a4a

Variables

This section is empty.

Functions

func CompleteHandshake

func CompleteHandshake(conn *m.Connection) (m.Packet, error)

func GetAllScenarii

func GetAllScenarii() map[string]Scenario

Types

type AbstractScenario

type AbstractScenario struct {
	// contains filtered or unexported fields
}

func (*AbstractScenario) CompleteHandshake

func (s *AbstractScenario) CompleteHandshake(conn *m.Connection, trace *m.Trace, handshakeErrorCode uint8, additionalAgents ...agents.Agent) *agents.ConnectionAgents

func (*AbstractScenario) IPv6

func (s *AbstractScenario) IPv6() bool

func (*AbstractScenario) Name

func (s *AbstractScenario) Name() string

func (*AbstractScenario) Timeout

func (s *AbstractScenario) Timeout() *time.Timer

func (*AbstractScenario) Version

func (s *AbstractScenario) Version() int

type AckECNScenario

type AckECNScenario struct {
	AbstractScenario
}

func NewAckECNScenario

func NewAckECNScenario() *AckECNScenario

func (*AckECNScenario) Run

func (s *AckECNScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type AckOnlyScenario

type AckOnlyScenario struct {
	AbstractScenario
}

func NewAckOnlyScenario

func NewAckOnlyScenario() *AckOnlyScenario

func (*AckOnlyScenario) Run

func (s *AckOnlyScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type AddressValidationScenario

type AddressValidationScenario struct {
	AbstractScenario
}

func NewAddressValidationScenario

func NewAddressValidationScenario() *AddressValidationScenario

func (*AddressValidationScenario) Run

func (s *AddressValidationScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type ConnectionMigrationScenario

type ConnectionMigrationScenario struct {
	AbstractScenario
}

func NewConnectionMigrationScenario

func NewConnectionMigrationScenario() *ConnectionMigrationScenario

func (*ConnectionMigrationScenario) Run

func (s *ConnectionMigrationScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type FlowControlScenario

type FlowControlScenario struct {
	AbstractScenario
}

func NewFlowControlScenario

func NewFlowControlScenario() *FlowControlScenario

func (*FlowControlScenario) Run

func (s *FlowControlScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type GetOnStream2Scenario

type GetOnStream2Scenario struct {
	AbstractScenario
}

func NewGetOnStream2Scenario

func NewGetOnStream2Scenario() *GetOnStream2Scenario

func (*GetOnStream2Scenario) Run

func (s *GetOnStream2Scenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type HandshakeRetransmissionScenario

type HandshakeRetransmissionScenario struct {
	AbstractScenario
}

func NewHandshakeRetransmissionScenario

func NewHandshakeRetransmissionScenario() *HandshakeRetransmissionScenario

func (*HandshakeRetransmissionScenario) Run

func (s *HandshakeRetransmissionScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type HandshakeScenario

type HandshakeScenario struct {
	AbstractScenario
}

func NewHandshakeScenario

func NewHandshakeScenario() *HandshakeScenario

func (*HandshakeScenario) Run

func (s *HandshakeScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type Handshakev6Scenario

type Handshakev6Scenario struct {
	AbstractScenario
}

func NewHandshakev6Scenario

func NewHandshakev6Scenario() *Handshakev6Scenario

func (*Handshakev6Scenario) Run

func (s *Handshakev6Scenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type MultiStreamScenario

type MultiStreamScenario struct {
	AbstractScenario
}

func NewMultiStreamScenario

func NewMultiStreamScenario() *MultiStreamScenario

func (*MultiStreamScenario) Run

func (s *MultiStreamScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type NewConnectionIDScenario

type NewConnectionIDScenario struct {
	AbstractScenario
}

func NewNewConnectionIDScenario

func NewNewConnectionIDScenario() *NewConnectionIDScenario

func (*NewConnectionIDScenario) Run

func (s *NewConnectionIDScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type PaddingScenario

type PaddingScenario struct {
	AbstractScenario
}

func NewPaddingScenario

func NewPaddingScenario() *PaddingScenario

func (*PaddingScenario) Run

func (s *PaddingScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type Scenario

type Scenario interface {
	Name() string
	Version() int
	IPv6() bool
	Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)
	Timeout() *time.Timer
}

type SimpleGetAndWaitScenario

type SimpleGetAndWaitScenario struct {
	AbstractScenario
}

func NewSimpleGetAndWaitScenario

func NewSimpleGetAndWaitScenario() *SimpleGetAndWaitScenario

func (*SimpleGetAndWaitScenario) Run

func (s *SimpleGetAndWaitScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type StopSendingOnReceiveStreamScenario

type StopSendingOnReceiveStreamScenario struct {
	AbstractScenario
}

func NewStopSendingOnReceiveStreamScenario

func NewStopSendingOnReceiveStreamScenario() *StopSendingOnReceiveStreamScenario

func (*StopSendingOnReceiveStreamScenario) Run

func (s *StopSendingOnReceiveStreamScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type StreamOpeningReorderingScenario

type StreamOpeningReorderingScenario struct {
	AbstractScenario
}

func NewStreamOpeningReorderingScenario

func NewStreamOpeningReorderingScenario() *StreamOpeningReorderingScenario

func (*StreamOpeningReorderingScenario) Run

func (s *StreamOpeningReorderingScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type TransportParameterScenario

type TransportParameterScenario struct {
	AbstractScenario
}

func NewTransportParameterScenario

func NewTransportParameterScenario() *TransportParameterScenario

func (*TransportParameterScenario) Run

func (s *TransportParameterScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type UnsupportedTLSVersionScenario

type UnsupportedTLSVersionScenario struct {
	AbstractScenario
}

func NewUnsupportedTLSVersionScenario

func NewUnsupportedTLSVersionScenario() *UnsupportedTLSVersionScenario

func (*UnsupportedTLSVersionScenario) Run

func (s *UnsupportedTLSVersionScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type VersionNegotiationScenario

type VersionNegotiationScenario struct {
	AbstractScenario
}

func NewVersionNegotiationScenario

func NewVersionNegotiationScenario() *VersionNegotiationScenario

func (*VersionNegotiationScenario) Run

func (s *VersionNegotiationScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

type ZeroRTTScenario

type ZeroRTTScenario struct {
	AbstractScenario
}

func NewZeroRTTScenario

func NewZeroRTTScenario() *ZeroRTTScenario

func (*ZeroRTTScenario) Run

func (s *ZeroRTTScenario) Run(conn *m.Connection, trace *m.Trace, preferredUrl string, debug bool)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL