session.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package kcp
  2. import (
  3. "errors"
  4. "net"
  5. "time"
  6. v2net "github.com/v2ray/v2ray-core/common/net"
  7. "github.com/v2ray/v2ray-core/transport/internet"
  8. "github.com/xtaci/kcp-go"
  9. )
  10. type KCPVlistener struct {
  11. lst *kcp.Listener
  12. previousSocketid map[int]uint32
  13. previousSocketid_mapid int
  14. }
  15. /*Accept Accept a KCP connection
  16. Since KCP is stateless, if package deliver after it was closed,
  17. It could be reconized as a new connection and call accept.
  18. If we can detect that the connection is of such a kind,
  19. we will discard that conn.
  20. */
  21. func (kvl *KCPVlistener) Accept() (internet.Connection, error) {
  22. conn, err := kvl.lst.Accept()
  23. if err != nil {
  24. return nil, err
  25. }
  26. if kvl.previousSocketid == nil {
  27. kvl.previousSocketid = make(map[int]uint32)
  28. }
  29. var badbit bool = false
  30. for _, key := range kvl.previousSocketid {
  31. if key == conn.GetConv() {
  32. badbit = true
  33. }
  34. }
  35. if badbit {
  36. conn.Close()
  37. return nil, errors.New("KCP:ConnDup, Don't worry~")
  38. } else {
  39. kvl.previousSocketid_mapid++
  40. kvl.previousSocketid[kvl.previousSocketid_mapid] = conn.GetConv()
  41. /*
  42. Here we assume that count(connection) < 512
  43. This won't always true.
  44. More work might be necessary to deal with this in a better way.
  45. */
  46. if kvl.previousSocketid_mapid >= 512 {
  47. delete(kvl.previousSocketid, kvl.previousSocketid_mapid-512)
  48. }
  49. }
  50. kcv := &KCPVconn{hc: conn}
  51. err = kcv.ApplyConf()
  52. if err != nil {
  53. return nil, err
  54. }
  55. return kcv, nil
  56. }
  57. func (kvl *KCPVlistener) Close() error {
  58. return kvl.lst.Close()
  59. }
  60. func (kvl *KCPVlistener) Addr() net.Addr {
  61. return kvl.lst.Addr()
  62. }
  63. type KCPVconn struct {
  64. hc *kcp.UDPSession
  65. conntokeep time.Time
  66. }
  67. //var counter int
  68. func (kcpvc *KCPVconn) Read(b []byte) (int, error) {
  69. ifb := time.Now().Add(time.Duration(effectiveConfig.ReadTimeout) * time.Second)
  70. if ifb.After(kcpvc.conntokeep) {
  71. kcpvc.conntokeep = ifb
  72. }
  73. kcpvc.hc.SetDeadline(kcpvc.conntokeep)
  74. return kcpvc.hc.Read(b)
  75. }
  76. func (kcpvc *KCPVconn) Write(b []byte) (int, error) {
  77. ifb := time.Now().Add(time.Duration(effectiveConfig.WriteTimeout) * time.Second)
  78. if ifb.After(kcpvc.conntokeep) {
  79. kcpvc.conntokeep = ifb
  80. }
  81. kcpvc.hc.SetDeadline(kcpvc.conntokeep)
  82. return kcpvc.hc.Write(b)
  83. }
  84. /*ApplyConf will apply kcpvc.conf to current Socket
  85. It is recommmanded to call this func once and only once
  86. */
  87. func (kcpvc *KCPVconn) ApplyConf() error {
  88. nodelay, interval, resend, nc := 0, 40, 0, 0
  89. switch effectiveConfig.Mode {
  90. case "normal":
  91. nodelay, interval, resend, nc = 0, 30, 2, 1
  92. case "fast":
  93. nodelay, interval, resend, nc = 0, 20, 2, 1
  94. case "fast2":
  95. nodelay, interval, resend, nc = 1, 20, 2, 1
  96. case "fast3":
  97. nodelay, interval, resend, nc = 1, 10, 2, 1
  98. }
  99. kcpvc.hc.SetNoDelay(nodelay, interval, resend, nc)
  100. kcpvc.hc.SetWindowSize(effectiveConfig.Sndwnd, effectiveConfig.Rcvwnd)
  101. kcpvc.hc.SetMtu(effectiveConfig.Mtu)
  102. kcpvc.hc.SetACKNoDelay(effectiveConfig.Acknodelay)
  103. kcpvc.hc.SetDSCP(effectiveConfig.Dscp)
  104. //counter++
  105. //log.Info(counter)
  106. return nil
  107. }
  108. /*Close Close the current conn
  109. We have to delay the close of Socket for a few second
  110. or the VMess EOF can be too late to send.
  111. */
  112. func (kcpvc *KCPVconn) Close() error {
  113. go func() {
  114. time.Sleep(2000 * time.Millisecond)
  115. //counter--
  116. //log.Info(counter)
  117. kcpvc.hc.Close()
  118. }()
  119. return nil
  120. }
  121. func (kcpvc *KCPVconn) LocalAddr() net.Addr {
  122. return kcpvc.hc.LocalAddr()
  123. }
  124. func (kcpvc *KCPVconn) RemoteAddr() net.Addr {
  125. return kcpvc.hc.RemoteAddr()
  126. }
  127. func (kcpvc *KCPVconn) SetDeadline(t time.Time) error {
  128. return kcpvc.hc.SetDeadline(t)
  129. }
  130. func (kcpvc *KCPVconn) SetReadDeadline(t time.Time) error {
  131. return kcpvc.hc.SetReadDeadline(t)
  132. }
  133. func (kcpvc *KCPVconn) SetWriteDeadline(t time.Time) error {
  134. return kcpvc.hc.SetWriteDeadline(t)
  135. }
  136. func (this *KCPVconn) Reusable() bool {
  137. return false
  138. }
  139. func (this *KCPVconn) SetReusable(b bool) {
  140. }
  141. func ListenKCP(address v2net.Address, port v2net.Port) (internet.Listener, error) {
  142. laddr := address.String() + ":" + port.String()
  143. crypt, _ := kcp.NewNoneBlockCrypt(nil)
  144. kcl, err := kcp.ListenWithOptions(effectiveConfig.Fec, laddr, crypt)
  145. kcvl := &KCPVlistener{lst: kcl}
  146. return kcvl, err
  147. }
  148. func init() {
  149. internet.KCPListenFunc = ListenKCP
  150. }