github.com/xmplusdev/xray-core@v1.8.10/proxy/vless/inbound/inbound.go (about)

     1  package inbound
     2  
     3  //go:generate go run github.com/xmplusdev/xray-core/common/errors/errorgen
     4  
     5  import (
     6  	"bytes"
     7  	"context"
     8  	gotls "crypto/tls"
     9  	"io"
    10  	"reflect"
    11  	"strconv"
    12  	"strings"
    13  	"time"
    14  	"unsafe"
    15  
    16  	"github.com/xmplusdev/xray-core/common"
    17  	"github.com/xmplusdev/xray-core/common/buf"
    18  	"github.com/xmplusdev/xray-core/common/errors"
    19  	"github.com/xmplusdev/xray-core/common/log"
    20  	"github.com/xmplusdev/xray-core/common/net"
    21  	"github.com/xmplusdev/xray-core/common/protocol"
    22  	"github.com/xmplusdev/xray-core/common/retry"
    23  	"github.com/xmplusdev/xray-core/common/session"
    24  	"github.com/xmplusdev/xray-core/common/signal"
    25  	"github.com/xmplusdev/xray-core/common/task"
    26  	"github.com/xmplusdev/xray-core/core"
    27  	"github.com/xmplusdev/xray-core/features/dns"
    28  	feature_inbound "github.com/xmplusdev/xray-core/features/inbound"
    29  	"github.com/xmplusdev/xray-core/features/policy"
    30  	"github.com/xmplusdev/xray-core/features/routing"
    31  	"github.com/xmplusdev/xray-core/proxy"
    32  	"github.com/xmplusdev/xray-core/proxy/vless"
    33  	"github.com/xmplusdev/xray-core/proxy/vless/encoding"
    34  	"github.com/xmplusdev/xray-core/transport/internet/reality"
    35  	"github.com/xmplusdev/xray-core/transport/internet/stat"
    36  	"github.com/xmplusdev/xray-core/transport/internet/tls"
    37  )
    38  
    39  func init() {
    40  	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
    41  		var dc dns.Client
    42  		if err := core.RequireFeatures(ctx, func(d dns.Client) error {
    43  			dc = d
    44  			return nil
    45  		}); err != nil {
    46  			return nil, err
    47  		}
    48  		return New(ctx, config.(*Config), dc)
    49  	}))
    50  }
    51  
    52  // Handler is an inbound connection handler that handles messages in VLess protocol.
    53  type Handler struct {
    54  	inboundHandlerManager feature_inbound.Manager
    55  	policyManager         policy.Manager
    56  	validator             *vless.Validator
    57  	dns                   dns.Client
    58  	fallbacks             map[string]map[string]map[string]*Fallback // or nil
    59  	// regexps               map[string]*regexp.Regexp       // or nil
    60  }
    61  
    62  // New creates a new VLess inbound handler.
    63  func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) {
    64  	v := core.MustFromContext(ctx)
    65  	handler := &Handler{
    66  		inboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager),
    67  		policyManager:         v.GetFeature(policy.ManagerType()).(policy.Manager),
    68  		validator:             new(vless.Validator),
    69  		dns:                   dc,
    70  	}
    71  
    72  	for _, user := range config.Clients {
    73  		u, err := user.ToMemoryUser()
    74  		if err != nil {
    75  			return nil, newError("failed to get VLESS user").Base(err).AtError()
    76  		}
    77  		if err := handler.AddUser(ctx, u); err != nil {
    78  			return nil, newError("failed to initiate user").Base(err).AtError()
    79  		}
    80  	}
    81  
    82  	if config.Fallbacks != nil {
    83  		handler.fallbacks = make(map[string]map[string]map[string]*Fallback)
    84  		// handler.regexps = make(map[string]*regexp.Regexp)
    85  		for _, fb := range config.Fallbacks {
    86  			if handler.fallbacks[fb.Name] == nil {
    87  				handler.fallbacks[fb.Name] = make(map[string]map[string]*Fallback)
    88  			}
    89  			if handler.fallbacks[fb.Name][fb.Alpn] == nil {
    90  				handler.fallbacks[fb.Name][fb.Alpn] = make(map[string]*Fallback)
    91  			}
    92  			handler.fallbacks[fb.Name][fb.Alpn][fb.Path] = fb
    93  			/*
    94  				if fb.Path != "" {
    95  					if r, err := regexp.Compile(fb.Path); err != nil {
    96  						return nil, newError("invalid path regexp").Base(err).AtError()
    97  					} else {
    98  						handler.regexps[fb.Path] = r
    99  					}
   100  				}
   101  			*/
   102  		}
   103  		if handler.fallbacks[""] != nil {
   104  			for name, apfb := range handler.fallbacks {
   105  				if name != "" {
   106  					for alpn := range handler.fallbacks[""] {
   107  						if apfb[alpn] == nil {
   108  							apfb[alpn] = make(map[string]*Fallback)
   109  						}
   110  					}
   111  				}
   112  			}
   113  		}
   114  		for _, apfb := range handler.fallbacks {
   115  			if apfb[""] != nil {
   116  				for alpn, pfb := range apfb {
   117  					if alpn != "" { // && alpn != "h2" {
   118  						for path, fb := range apfb[""] {
   119  							if pfb[path] == nil {
   120  								pfb[path] = fb
   121  							}
   122  						}
   123  					}
   124  				}
   125  			}
   126  		}
   127  		if handler.fallbacks[""] != nil {
   128  			for name, apfb := range handler.fallbacks {
   129  				if name != "" {
   130  					for alpn, pfb := range handler.fallbacks[""] {
   131  						for path, fb := range pfb {
   132  							if apfb[alpn][path] == nil {
   133  								apfb[alpn][path] = fb
   134  							}
   135  						}
   136  					}
   137  				}
   138  			}
   139  		}
   140  	}
   141  
   142  	return handler, nil
   143  }
   144  
   145  func isMuxAndNotXUDP(request *protocol.RequestHeader, first *buf.Buffer) bool {
   146  	if request.Command != protocol.RequestCommandMux {
   147  		return false
   148  	}
   149  	if first.Len() < 7 {
   150  		return true
   151  	}
   152  	firstBytes := first.Bytes()
   153  	return !(firstBytes[2] == 0 && // ID high
   154  		firstBytes[3] == 0 && // ID low
   155  		firstBytes[6] == 2) // Network type: UDP
   156  }
   157  
   158  // Close implements common.Closable.Close().
   159  func (h *Handler) Close() error {
   160  	return errors.Combine(common.Close(h.validator))
   161  }
   162  
   163  // AddUser implements proxy.UserManager.AddUser().
   164  func (h *Handler) AddUser(ctx context.Context, u *protocol.MemoryUser) error {
   165  	return h.validator.Add(u)
   166  }
   167  
   168  // RemoveUser implements proxy.UserManager.RemoveUser().
   169  func (h *Handler) RemoveUser(ctx context.Context, e string) error {
   170  	return h.validator.Del(e)
   171  }
   172  
   173  // Network implements proxy.Inbound.Network().
   174  func (*Handler) Network() []net.Network {
   175  	return []net.Network{net.Network_TCP, net.Network_UNIX}
   176  }
   177  
   178  // Process implements proxy.Inbound.Process().
   179  func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error {
   180  	sid := session.ExportIDToError(ctx)
   181  
   182  	iConn := connection
   183  	if statConn, ok := iConn.(*stat.CounterConnection); ok {
   184  		iConn = statConn.Connection
   185  	}
   186  
   187  	sessionPolicy := h.policyManager.ForLevel(0)
   188  	if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {
   189  		return newError("unable to set read deadline").Base(err).AtWarning()
   190  	}
   191  
   192  	first := buf.FromBytes(make([]byte, buf.Size))
   193  	first.Clear()
   194  	firstLen, _ := first.ReadFrom(connection)
   195  	newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid)
   196  
   197  	reader := &buf.BufferedReader{
   198  		Reader: buf.NewReader(connection),
   199  		Buffer: buf.MultiBuffer{first},
   200  	}
   201  
   202  	var request *protocol.RequestHeader
   203  	var requestAddons *encoding.Addons
   204  	var err error
   205  
   206  	napfb := h.fallbacks
   207  	isfb := napfb != nil
   208  
   209  	if isfb && firstLen < 18 {
   210  		err = newError("fallback directly")
   211  	} else {
   212  		request, requestAddons, isfb, err = encoding.DecodeRequestHeader(isfb, first, reader, h.validator)
   213  	}
   214  
   215  	if err != nil {
   216  		if isfb {
   217  			if err := connection.SetReadDeadline(time.Time{}); err != nil {
   218  				newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
   219  			}
   220  			newError("fallback starts").Base(err).AtInfo().WriteToLog(sid)
   221  
   222  			name := ""
   223  			alpn := ""
   224  			if tlsConn, ok := iConn.(*tls.Conn); ok {
   225  				cs := tlsConn.ConnectionState()
   226  				name = cs.ServerName
   227  				alpn = cs.NegotiatedProtocol
   228  				newError("realName = " + name).AtInfo().WriteToLog(sid)
   229  				newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid)
   230  			} else if realityConn, ok := iConn.(*reality.Conn); ok {
   231  				cs := realityConn.ConnectionState()
   232  				name = cs.ServerName
   233  				alpn = cs.NegotiatedProtocol
   234  				newError("realName = " + name).AtInfo().WriteToLog(sid)
   235  				newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid)
   236  			}
   237  			name = strings.ToLower(name)
   238  			alpn = strings.ToLower(alpn)
   239  
   240  			if len(napfb) > 1 || napfb[""] == nil {
   241  				if name != "" && napfb[name] == nil {
   242  					match := ""
   243  					for n := range napfb {
   244  						if n != "" && strings.Contains(name, n) && len(n) > len(match) {
   245  							match = n
   246  						}
   247  					}
   248  					name = match
   249  				}
   250  			}
   251  
   252  			if napfb[name] == nil {
   253  				name = ""
   254  			}
   255  			apfb := napfb[name]
   256  			if apfb == nil {
   257  				return newError(`failed to find the default "name" config`).AtWarning()
   258  			}
   259  
   260  			if apfb[alpn] == nil {
   261  				alpn = ""
   262  			}
   263  			pfb := apfb[alpn]
   264  			if pfb == nil {
   265  				return newError(`failed to find the default "alpn" config`).AtWarning()
   266  			}
   267  
   268  			path := ""
   269  			if len(pfb) > 1 || pfb[""] == nil {
   270  				/*
   271  					if lines := bytes.Split(firstBytes, []byte{'\r', '\n'}); len(lines) > 1 {
   272  						if s := bytes.Split(lines[0], []byte{' '}); len(s) == 3 {
   273  							if len(s[0]) < 8 && len(s[1]) > 0 && len(s[2]) == 8 {
   274  								newError("realPath = " + string(s[1])).AtInfo().WriteToLog(sid)
   275  								for _, fb := range pfb {
   276  									if fb.Path != "" && h.regexps[fb.Path].Match(s[1]) {
   277  										path = fb.Path
   278  										break
   279  									}
   280  								}
   281  							}
   282  						}
   283  					}
   284  				*/
   285  				if firstLen >= 18 && first.Byte(4) != '*' { // not h2c
   286  					firstBytes := first.Bytes()
   287  					for i := 4; i <= 8; i++ { // 5 -> 9
   288  						if firstBytes[i] == '/' && firstBytes[i-1] == ' ' {
   289  							search := len(firstBytes)
   290  							if search > 64 {
   291  								search = 64 // up to about 60
   292  							}
   293  							for j := i + 1; j < search; j++ {
   294  								k := firstBytes[j]
   295  								if k == '\r' || k == '\n' { // avoid logging \r or \n
   296  									break
   297  								}
   298  								if k == '?' || k == ' ' {
   299  									path = string(firstBytes[i:j])
   300  									newError("realPath = " + path).AtInfo().WriteToLog(sid)
   301  									if pfb[path] == nil {
   302  										path = ""
   303  									}
   304  									break
   305  								}
   306  							}
   307  							break
   308  						}
   309  					}
   310  				}
   311  			}
   312  			fb := pfb[path]
   313  			if fb == nil {
   314  				return newError(`failed to find the default "path" config`).AtWarning()
   315  			}
   316  
   317  			ctx, cancel := context.WithCancel(ctx)
   318  			timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
   319  			ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)
   320  
   321  			var conn net.Conn
   322  			if err := retry.ExponentialBackoff(5, 100).On(func() error {
   323  				var dialer net.Dialer
   324  				conn, err = dialer.DialContext(ctx, fb.Type, fb.Dest)
   325  				if err != nil {
   326  					return err
   327  				}
   328  				return nil
   329  			}); err != nil {
   330  				return newError("failed to dial to " + fb.Dest).Base(err).AtWarning()
   331  			}
   332  			defer conn.Close()
   333  
   334  			serverReader := buf.NewReader(conn)
   335  			serverWriter := buf.NewWriter(conn)
   336  
   337  			postRequest := func() error {
   338  				defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
   339  				if fb.Xver != 0 {
   340  					ipType := 4
   341  					remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String())
   342  					if err != nil {
   343  						ipType = 0
   344  					}
   345  					localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String())
   346  					if err != nil {
   347  						ipType = 0
   348  					}
   349  					if ipType == 4 {
   350  						for i := 0; i < len(remoteAddr); i++ {
   351  							if remoteAddr[i] == ':' {
   352  								ipType = 6
   353  								break
   354  							}
   355  						}
   356  					}
   357  					pro := buf.New()
   358  					defer pro.Release()
   359  					switch fb.Xver {
   360  					case 1:
   361  						if ipType == 0 {
   362  							pro.Write([]byte("PROXY UNKNOWN\r\n"))
   363  							break
   364  						}
   365  						if ipType == 4 {
   366  							pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
   367  						} else {
   368  							pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
   369  						}
   370  					case 2:
   371  						pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A")) // signature
   372  						if ipType == 0 {
   373  							pro.Write([]byte("\x20\x00\x00\x00")) // v2 + LOCAL + UNSPEC + UNSPEC + 0 bytes
   374  							break
   375  						}
   376  						if ipType == 4 {
   377  							pro.Write([]byte("\x21\x11\x00\x0C")) // v2 + PROXY + AF_INET + STREAM + 12 bytes
   378  							pro.Write(net.ParseIP(remoteAddr).To4())
   379  							pro.Write(net.ParseIP(localAddr).To4())
   380  						} else {
   381  							pro.Write([]byte("\x21\x21\x00\x24")) // v2 + PROXY + AF_INET6 + STREAM + 36 bytes
   382  							pro.Write(net.ParseIP(remoteAddr).To16())
   383  							pro.Write(net.ParseIP(localAddr).To16())
   384  						}
   385  						p1, _ := strconv.ParseUint(remotePort, 10, 16)
   386  						p2, _ := strconv.ParseUint(localPort, 10, 16)
   387  						pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)})
   388  					}
   389  					if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {
   390  						return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning()
   391  					}
   392  				}
   393  				if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {
   394  					return newError("failed to fallback request payload").Base(err).AtInfo()
   395  				}
   396  				return nil
   397  			}
   398  
   399  			writer := buf.NewWriter(connection)
   400  
   401  			getResponse := func() error {
   402  				defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
   403  				if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil {
   404  					return newError("failed to deliver response payload").Base(err).AtInfo()
   405  				}
   406  				return nil
   407  			}
   408  
   409  			if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil {
   410  				common.Interrupt(serverReader)
   411  				common.Interrupt(serverWriter)
   412  				return newError("fallback ends").Base(err).AtInfo()
   413  			}
   414  			return nil
   415  		}
   416  
   417  		if errors.Cause(err) != io.EOF {
   418  			log.Record(&log.AccessMessage{
   419  				From:   connection.RemoteAddr(),
   420  				To:     "",
   421  				Status: log.AccessRejected,
   422  				Reason: err,
   423  			})
   424  			err = newError("invalid request from ", connection.RemoteAddr()).Base(err).AtInfo()
   425  		}
   426  		return err
   427  	}
   428  
   429  	if err := connection.SetReadDeadline(time.Time{}); err != nil {
   430  		newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
   431  	}
   432  	newError("received request for ", request.Destination()).AtInfo().WriteToLog(sid)
   433  
   434  	inbound := session.InboundFromContext(ctx)
   435  	if inbound == nil {
   436  		panic("no inbound metadata")
   437  	}
   438  	inbound.Name = "vless"
   439  	inbound.User = request.User
   440  
   441  	account := request.User.Account.(*vless.MemoryAccount)
   442  
   443  	responseAddons := &encoding.Addons{
   444  		// Flow: requestAddons.Flow,
   445  	}
   446  
   447  	var input *bytes.Reader
   448  	var rawInput *bytes.Buffer
   449  	switch requestAddons.Flow {
   450  	case vless.XRV:
   451  		if account.Flow == requestAddons.Flow {
   452  			inbound.SetCanSpliceCopy(2)
   453  			switch request.Command {
   454  			case protocol.RequestCommandUDP:
   455  				return newError(requestAddons.Flow + " doesn't support UDP").AtWarning()
   456  			case protocol.RequestCommandMux:
   457  				fallthrough // we will break Mux connections that contain TCP requests
   458  			case protocol.RequestCommandTCP:
   459  				var t reflect.Type
   460  				var p uintptr
   461  				if tlsConn, ok := iConn.(*tls.Conn); ok {
   462  					if tlsConn.ConnectionState().Version != gotls.VersionTLS13 {
   463  						return newError(`failed to use `+requestAddons.Flow+`, found outer tls version `, tlsConn.ConnectionState().Version).AtWarning()
   464  					}
   465  					t = reflect.TypeOf(tlsConn.Conn).Elem()
   466  					p = uintptr(unsafe.Pointer(tlsConn.Conn))
   467  				} else if realityConn, ok := iConn.(*reality.Conn); ok {
   468  					t = reflect.TypeOf(realityConn.Conn).Elem()
   469  					p = uintptr(unsafe.Pointer(realityConn.Conn))
   470  				} else {
   471  					return newError("XTLS only supports TLS and REALITY directly for now.").AtWarning()
   472  				}
   473  				i, _ := t.FieldByName("input")
   474  				r, _ := t.FieldByName("rawInput")
   475  				input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset))
   476  				rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset))
   477  			}
   478  		} else {
   479  			return newError(account.ID.String() + " is not able to use " + requestAddons.Flow).AtWarning()
   480  		}
   481  	case "":
   482  		inbound.SetCanSpliceCopy(3)
   483  		if account.Flow == vless.XRV && (request.Command == protocol.RequestCommandTCP || isMuxAndNotXUDP(request, first)) {
   484  			return newError(account.ID.String() + " is not able to use \"\". Note that the pure TLS proxy has certain TLS in TLS characters.").AtWarning()
   485  		}
   486  	default:
   487  		return newError("unknown request flow " + requestAddons.Flow).AtWarning()
   488  	}
   489  
   490  	if request.Command != protocol.RequestCommandMux {
   491  		ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
   492  			From:   connection.RemoteAddr(),
   493  			To:     request.Destination(),
   494  			Status: log.AccessAccepted,
   495  			Reason: "",
   496  			Email:  request.User.Email,
   497  		})
   498  	} else if account.Flow == vless.XRV {
   499  		ctx = session.ContextWithAllowedNetwork(ctx, net.Network_UDP)
   500  	}
   501  
   502  	sessionPolicy = h.policyManager.ForLevel(request.User.Level)
   503  	ctx, cancel := context.WithCancel(ctx)
   504  	timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
   505  	ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)
   506  
   507  	link, err := dispatcher.Dispatch(ctx, request.Destination())
   508  	if err != nil {
   509  		return newError("failed to dispatch request to ", request.Destination()).Base(err).AtWarning()
   510  	}
   511  
   512  	serverReader := link.Reader // .(*pipe.Reader)
   513  	serverWriter := link.Writer // .(*pipe.Writer)
   514  	trafficState := proxy.NewTrafficState(account.ID.Bytes())
   515  	postRequest := func() error {
   516  		defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
   517  
   518  		// default: clientReader := reader
   519  		clientReader := encoding.DecodeBodyAddons(reader, request, requestAddons)
   520  
   521  		var err error
   522  
   523  		if requestAddons.Flow == vless.XRV {
   524  			ctx1 := session.ContextWithInbound(ctx, nil) // TODO enable splice
   525  			clientReader = proxy.NewVisionReader(clientReader, trafficState, ctx1)
   526  			err = encoding.XtlsRead(clientReader, serverWriter, timer, connection, input, rawInput, trafficState, ctx1)
   527  		} else {
   528  			// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
   529  			err = buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer))
   530  		}
   531  
   532  		if err != nil {
   533  			return newError("failed to transfer request payload").Base(err).AtInfo()
   534  		}
   535  
   536  		return nil
   537  	}
   538  
   539  	getResponse := func() error {
   540  		defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
   541  
   542  		bufferWriter := buf.NewBufferedWriter(buf.NewWriter(connection))
   543  		if err := encoding.EncodeResponseHeader(bufferWriter, request, responseAddons); err != nil {
   544  			return newError("failed to encode response header").Base(err).AtWarning()
   545  		}
   546  
   547  		// default: clientWriter := bufferWriter
   548  		clientWriter := encoding.EncodeBodyAddons(bufferWriter, request, requestAddons, trafficState, ctx)
   549  		multiBuffer, err1 := serverReader.ReadMultiBuffer()
   550  		if err1 != nil {
   551  			return err1 // ...
   552  		}
   553  		if err := clientWriter.WriteMultiBuffer(multiBuffer); err != nil {
   554  			return err // ...
   555  		}
   556  		// Flush; bufferWriter.WriteMultiBufer now is bufferWriter.writer.WriteMultiBuffer
   557  		if err := bufferWriter.SetBuffered(false); err != nil {
   558  			return newError("failed to write A response payload").Base(err).AtWarning()
   559  		}
   560  
   561  		var err error
   562  		if requestAddons.Flow == vless.XRV {
   563  			err = encoding.XtlsWrite(serverReader, clientWriter, timer, connection, trafficState, ctx)
   564  		} else {
   565  			// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
   566  			err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer))
   567  		}
   568  		if err != nil {
   569  			return newError("failed to transfer response payload").Base(err).AtInfo()
   570  		}
   571  		// Indicates the end of response payload.
   572  		switch responseAddons.Flow {
   573  		default:
   574  		}
   575  
   576  		return nil
   577  	}
   578  
   579  	if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), getResponse); err != nil {
   580  		common.Interrupt(serverReader)
   581  		common.Interrupt(serverWriter)
   582  		return newError("connection ends").Base(err).AtInfo()
   583  	}
   584  
   585  	return nil
   586  }