github.com/geph-official/geph2@v0.22.6-0.20210211030601-f527cb59b0df/libs/kcp-go/tx_linux.go (about)

     1  // +build linux
     2  
     3  package kcp
     4  
     5  import (
     6  	"log"
     7  	"net"
     8  	"os"
     9  	"sync/atomic"
    10  
    11  	"github.com/pkg/errors"
    12  	"golang.org/x/net/ipv4"
    13  )
    14  
    15  func (s *UDPSession) tx(txqueue []ipv4.Message) {
    16  	// default version
    17  	if s.xconn == nil || s.xconnWriteError != nil {
    18  		s.defaultTx(txqueue)
    19  		return
    20  	}
    21  
    22  	// x/net version
    23  	nbytes := 0
    24  	npkts := 0
    25  	for len(txqueue) > 0 {
    26  		log.Println("batching", len(txqueue))
    27  		if n, err := s.xconn.WriteBatch(txqueue, 0); err == nil {
    28  			for k := range txqueue[:n] {
    29  				nbytes += len(txqueue[k].Buffers[0])
    30  			}
    31  			npkts += n
    32  			txqueue = txqueue[n:]
    33  		} else {
    34  			// compatibility issue:
    35  			// for linux kernel<=2.6.32, support for sendmmsg is not available
    36  			// an error of type os.SyscallError will be returned
    37  			if operr, ok := err.(*net.OpError); ok {
    38  				if se, ok := operr.Err.(*os.SyscallError); ok {
    39  					if se.Syscall == "sendmmsg" {
    40  						s.xconnWriteError = se
    41  						s.defaultTx(txqueue)
    42  						return
    43  					}
    44  				}
    45  			}
    46  			s.notifyWriteError(errors.WithStack(err))
    47  			break
    48  		}
    49  	}
    50  
    51  	atomic.AddUint64(&DefaultSnmp.OutPkts, uint64(npkts))
    52  	atomic.AddUint64(&DefaultSnmp.OutBytes, uint64(nbytes))
    53  }