@@ -699,25 +699,50 @@ type CustomSockoptConfig struct {
699699 Type string `json:"type"`
700700}
701701
702+ type HappyEyeballsConfig struct {
703+ PrioritizeIPv6 bool `json:"prioritizeIPv6"`
704+ TryDelayMs uint64 `json:"tryDelayMs"`
705+ Interleave uint32 `json:"interleave"`
706+ MaxConcurrentTry uint32 `json:"maxConcurrentTry"`
707+ }
708+
709+ func (h * HappyEyeballsConfig ) UnmarshalJSON (data []byte ) error {
710+ var innerHappyEyeballsConfig = struct {
711+ PrioritizeIPv6 bool `json:"prioritizeIPv6"`
712+ TryDelayMs uint64 `json:"tryDelayMs"`
713+ Interleave uint32 `json:"interleave"`
714+ MaxConcurrentTry uint32 `json:"maxConcurrentTry"`
715+ }{PrioritizeIPv6 : false , Interleave : 1 , TryDelayMs : 0 , MaxConcurrentTry : 4 }
716+ if err := json .Unmarshal (data , & innerHappyEyeballsConfig ); err != nil {
717+ return err
718+ }
719+ h .PrioritizeIPv6 = innerHappyEyeballsConfig .PrioritizeIPv6
720+ h .TryDelayMs = innerHappyEyeballsConfig .TryDelayMs
721+ h .Interleave = innerHappyEyeballsConfig .Interleave
722+ h .MaxConcurrentTry = innerHappyEyeballsConfig .MaxConcurrentTry
723+ return nil
724+ }
725+
702726type SocketConfig struct {
703- Mark int32 `json:"mark"`
704- TFO interface {} `json:"tcpFastOpen"`
705- TProxy string `json:"tproxy"`
706- AcceptProxyProtocol bool `json:"acceptProxyProtocol"`
707- DomainStrategy string `json:"domainStrategy"`
708- DialerProxy string `json:"dialerProxy"`
709- TCPKeepAliveInterval int32 `json:"tcpKeepAliveInterval"`
710- TCPKeepAliveIdle int32 `json:"tcpKeepAliveIdle"`
711- TCPCongestion string `json:"tcpCongestion"`
712- TCPWindowClamp int32 `json:"tcpWindowClamp"`
713- TCPMaxSeg int32 `json:"tcpMaxSeg"`
714- Penetrate bool `json:"penetrate"`
715- TCPUserTimeout int32 `json:"tcpUserTimeout"`
716- V6only bool `json:"v6only"`
717- Interface string `json:"interface"`
718- TcpMptcp bool `json:"tcpMptcp"`
719- CustomSockopt []* CustomSockoptConfig `json:"customSockopt"`
720- AddressPortStrategy string `json:"addressPortStrategy"`
727+ Mark int32 `json:"mark"`
728+ TFO interface {} `json:"tcpFastOpen"`
729+ TProxy string `json:"tproxy"`
730+ AcceptProxyProtocol bool `json:"acceptProxyProtocol"`
731+ DomainStrategy string `json:"domainStrategy"`
732+ DialerProxy string `json:"dialerProxy"`
733+ TCPKeepAliveInterval int32 `json:"tcpKeepAliveInterval"`
734+ TCPKeepAliveIdle int32 `json:"tcpKeepAliveIdle"`
735+ TCPCongestion string `json:"tcpCongestion"`
736+ TCPWindowClamp int32 `json:"tcpWindowClamp"`
737+ TCPMaxSeg int32 `json:"tcpMaxSeg"`
738+ Penetrate bool `json:"penetrate"`
739+ TCPUserTimeout int32 `json:"tcpUserTimeout"`
740+ V6only bool `json:"v6only"`
741+ Interface string `json:"interface"`
742+ TcpMptcp bool `json:"tcpMptcp"`
743+ CustomSockopt []* CustomSockoptConfig `json:"customSockopt"`
744+ AddressPortStrategy string `json:"addressPortStrategy"`
745+ HappyEyeballsSettings * HappyEyeballsConfig `json:"happyEyeballs"`
721746}
722747
723748// Build implements Buildable.
@@ -809,6 +834,14 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
809834 return nil , errors .New ("unsupported address and port strategy: " , c .AddressPortStrategy )
810835 }
811836
837+ var happyEyeballs = & internet.HappyEyeballsConfig {Interleave : 1 , PrioritizeIpv6 : false , TryDelayMs : 0 , MaxConcurrentTry : 4 }
838+ if c .HappyEyeballsSettings != nil {
839+ happyEyeballs .PrioritizeIpv6 = c .HappyEyeballsSettings .PrioritizeIPv6
840+ happyEyeballs .Interleave = c .HappyEyeballsSettings .Interleave
841+ happyEyeballs .TryDelayMs = c .HappyEyeballsSettings .TryDelayMs
842+ happyEyeballs .MaxConcurrentTry = c .HappyEyeballsSettings .MaxConcurrentTry
843+ }
844+
812845 return & internet.SocketConfig {
813846 Mark : c .Mark ,
814847 Tfo : tfo ,
@@ -828,6 +861,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
828861 TcpMptcp : c .TcpMptcp ,
829862 CustomSockopt : customSockopts ,
830863 AddressPortStrategy : addressPortStrategy ,
864+ HappyEyeballs : happyEyeballs ,
831865 }, nil
832866}
833867
0 commit comments