@@ -510,7 +510,8 @@ func (r *Router) Stop() {
510510// processOnionCfg is a set of config values that can be used to modify how an
511511// onion is processed.
512512type processOnionCfg struct {
513- blindingPoint * btcec.PublicKey
513+ blindingPoint * btcec.PublicKey
514+ tlvPayloadOnly bool
514515}
515516
516517// ProcessOnionOpt defines the signature of a function option that can be used
@@ -525,6 +526,14 @@ func WithBlindingPoint(point *btcec.PublicKey) ProcessOnionOpt {
525526 }
526527}
527528
529+ // WithTLVPayloadOnly is a functional option that signals that the onion packet
530+ // being processed is from onion message.
531+ func WithTLVPayloadOnly () ProcessOnionOpt {
532+ return func (cfg * processOnionCfg ) {
533+ cfg .tlvPayloadOnly = true
534+ }
535+ }
536+
528537// ProcessOnionPacket processes an incoming onion packet which has been forward
529538// to the target Sphinx router. If the encoded ephemeral key isn't on the
530539// target Elliptic Curve, then the packet is rejected. Similarly, if the
@@ -560,7 +569,9 @@ func (r *Router) ProcessOnionPacket(onionPkt *OnionPacket, assocData []byte,
560569 // Continue to optimistically process this packet, deferring replay
561570 // protection until the end to reduce the penalty of multiple IO
562571 // operations.
563- packet , err := processOnionPacket (onionPkt , & sharedSecret , assocData )
572+ packet , err := processOnionPacket (
573+ onionPkt , & sharedSecret , assocData , cfg .tlvPayloadOnly ,
574+ )
564575 if err != nil {
565576 return nil , err
566577 }
@@ -594,7 +605,9 @@ func (r *Router) ReconstructOnionPacket(onionPkt *OnionPacket, assocData []byte,
594605 return nil , err
595606 }
596607
597- return processOnionPacket (onionPkt , & sharedSecret , assocData )
608+ return processOnionPacket (
609+ onionPkt , & sharedSecret , assocData , cfg .tlvPayloadOnly ,
610+ )
598611}
599612
600613// DecryptBlindedHopData uses the router's private key to decrypt data encrypted
@@ -625,7 +638,8 @@ func (r *Router) OnionPublicKey() *btcec.PublicKey {
625638// packet. This function returns the next inner onion packet layer, along with
626639// the hop data extracted from the outer onion packet.
627640func unwrapPacket (onionPkt * OnionPacket , sharedSecret * Hash256 ,
628- assocData []byte ) (* OnionPacket , * HopPayload , error ) {
641+ assocData []byte , tlvPayloadOnly bool ) (* OnionPacket , * HopPayload ,
642+ error ) {
629643
630644 dhKey := onionPkt .EphemeralKey
631645 routeInfo := onionPkt .RoutingInfo
@@ -660,8 +674,16 @@ func unwrapPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
660674 // With the MAC checked, and the payload decrypted, we can now parse
661675 // out the payload so we can derive the specified forwarding
662676 // instructions.
663- var hopPayload HopPayload
664- if err := hopPayload .Decode (bytes .NewReader (hopInfo [:])); err != nil {
677+ hopPayload := HopPayload {}
678+ if tlvPayloadOnly {
679+ // If the payload is assured to be TLV, we don't have to support
680+ // legacy payloads, but we do support zero-length payloads. By
681+ // specifically setting the type to TLV, we ensure that the
682+ // payload is treated as such.
683+ hopPayload .Type = PayloadTLV
684+ }
685+ err := hopPayload .Decode (bytes .NewReader (hopInfo [:]))
686+ if err != nil {
665687 return nil , nil , err
666688 }
667689
@@ -683,7 +705,7 @@ func unwrapPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
683705// packets. The processed packets returned from this method should only be used
684706// if the packet was not flagged as a replayed packet.
685707func processOnionPacket (onionPkt * OnionPacket , sharedSecret * Hash256 ,
686- assocData []byte ) (* ProcessedPacket , error ) {
708+ assocData []byte , tlvPayloadOnly bool ) (* ProcessedPacket , error ) {
687709
688710 // First, we'll unwrap an initial layer of the onion packet. Typically,
689711 // we'll only have a single layer to unwrap, However, if the sender has
@@ -693,7 +715,7 @@ func processOnionPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
693715 // they can properly check the HMAC and unwrap a layer for their
694716 // handoff hop.
695717 innerPkt , outerHopPayload , err := unwrapPacket (
696- onionPkt , sharedSecret , assocData ,
718+ onionPkt , sharedSecret , assocData , tlvPayloadOnly ,
697719 )
698720 if err != nil {
699721 return nil , err
@@ -703,7 +725,7 @@ func processOnionPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
703725 // However if the uncovered 'nextMac' is all zeroes, then this
704726 // indicates that we're the final hop in the route.
705727 var action ProcessCode = MoreHops
706- if bytes .Compare (zeroHMAC [:], outerHopPayload .HMAC [:]) == 0 {
728+ if bytes .Equal (zeroHMAC [:], outerHopPayload .HMAC [:]) {
707729 action = ExitNode
708730 }
709731
@@ -794,7 +816,9 @@ func (t *Tx) ProcessOnionPacket(seqNum uint16, onionPkt *OnionPacket,
794816 // Continue to optimistically process this packet, deferring replay
795817 // protection until the end to reduce the penalty of multiple IO
796818 // operations.
797- packet , err := processOnionPacket (onionPkt , & sharedSecret , assocData )
819+ packet , err := processOnionPacket (
820+ onionPkt , & sharedSecret , assocData , cfg .tlvPayloadOnly ,
821+ )
798822 if err != nil {
799823 return err
800824 }
0 commit comments