tx_linux.go 1.1 KB

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