conn.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. package mux
  2. import (
  3. "errors"
  4. "io"
  5. "net"
  6. "sync"
  7. "sync/atomic"
  8. "time"
  9. "github.com/cnlh/nps/lib/common"
  10. )
  11. type conn struct {
  12. net.Conn
  13. getStatusCh chan struct{}
  14. connStatusOkCh chan struct{}
  15. connStatusFailCh chan struct{}
  16. connId int32
  17. isClose bool
  18. closeFlag bool // close conn flag
  19. receiveWindow *ReceiveWindow
  20. sendWindow *SendWindow
  21. once sync.Once
  22. label string
  23. }
  24. func NewConn(connId int32, mux *Mux, label ...string) *conn {
  25. c := &conn{
  26. getStatusCh: make(chan struct{}),
  27. connStatusOkCh: make(chan struct{}),
  28. connStatusFailCh: make(chan struct{}),
  29. connId: connId,
  30. receiveWindow: new(ReceiveWindow),
  31. sendWindow: new(SendWindow),
  32. once: sync.Once{},
  33. }
  34. if len(label) > 0 {
  35. c.label = label[0]
  36. }
  37. c.receiveWindow.New(mux)
  38. c.sendWindow.New(mux)
  39. //logm := &connLog{
  40. // startTime: time.Now(),
  41. // isClose: false,
  42. // logs: []string{c.label + "new conn success"},
  43. //}
  44. //setM(label[0], int(connId), logm)
  45. return c
  46. }
  47. func (s *conn) Read(buf []byte) (n int, err error) {
  48. if s.isClose || buf == nil {
  49. return 0, errors.New("the conn has closed")
  50. }
  51. if len(buf) == 0 {
  52. return 0, nil
  53. }
  54. // waiting for takeout from receive window finish or timeout
  55. n, err = s.receiveWindow.Read(buf, s.connId)
  56. //var errstr string
  57. //if err == nil {
  58. // errstr = "err:nil"
  59. //} else {
  60. // errstr = err.Error()
  61. //}
  62. //d := getM(s.label, int(s.connId))
  63. //d.logs = append(d.logs, s.label+"read "+strconv.Itoa(n)+" "+errstr+" "+string(buf[:100]))
  64. //setM(s.label, int(s.connId), d)
  65. return
  66. }
  67. func (s *conn) Write(buf []byte) (n int, err error) {
  68. if s.isClose {
  69. return 0, errors.New("the conn has closed")
  70. }
  71. if s.closeFlag {
  72. //s.Close()
  73. return 0, errors.New("io: write on closed conn")
  74. }
  75. if len(buf) == 0 {
  76. return 0, nil
  77. }
  78. //logs.Warn("write buf", len(buf))
  79. n, err = s.sendWindow.WriteFull(buf, s.connId)
  80. return
  81. }
  82. func (s *conn) Close() (err error) {
  83. s.once.Do(s.closeProcess)
  84. return
  85. }
  86. func (s *conn) closeProcess() {
  87. s.isClose = true
  88. s.receiveWindow.mux.connMap.Delete(s.connId)
  89. if !s.receiveWindow.mux.IsClose {
  90. // if server or user close the conn while reading, will get a io.EOF
  91. // and this Close method will be invoke, send this signal to close other side
  92. s.receiveWindow.mux.sendInfo(common.MUX_CONN_CLOSE, s.connId, nil)
  93. }
  94. s.sendWindow.CloseWindow()
  95. s.receiveWindow.CloseWindow()
  96. //d := getM(s.label, int(s.connId))
  97. //d.isClose = true
  98. //d.logs = append(d.logs, s.label+"close "+time.Now().String())
  99. //setM(s.label, int(s.connId), d)
  100. return
  101. }
  102. func (s *conn) LocalAddr() net.Addr {
  103. return s.receiveWindow.mux.conn.LocalAddr()
  104. }
  105. func (s *conn) RemoteAddr() net.Addr {
  106. return s.receiveWindow.mux.conn.RemoteAddr()
  107. }
  108. func (s *conn) SetDeadline(t time.Time) error {
  109. _ = s.SetReadDeadline(t)
  110. _ = s.SetWriteDeadline(t)
  111. return nil
  112. }
  113. func (s *conn) SetReadDeadline(t time.Time) error {
  114. s.receiveWindow.SetTimeOut(t)
  115. return nil
  116. }
  117. func (s *conn) SetWriteDeadline(t time.Time) error {
  118. s.sendWindow.SetTimeOut(t)
  119. return nil
  120. }
  121. type window struct {
  122. off uint32
  123. maxSize uint32
  124. closeOp bool
  125. closeOpCh chan struct{}
  126. mux *Mux
  127. }
  128. func (Self *window) New() {
  129. Self.closeOpCh = make(chan struct{}, 2)
  130. }
  131. func (Self *window) CloseWindow() {
  132. if !Self.closeOp {
  133. Self.closeOp = true
  134. Self.closeOpCh <- struct{}{}
  135. Self.closeOpCh <- struct{}{}
  136. }
  137. }
  138. type ReceiveWindow struct {
  139. bufQueue ReceiveWindowQueue
  140. element *ListElement
  141. readLength uint32
  142. readOp chan struct{}
  143. readWait bool
  144. windowFull uint32
  145. count int8
  146. //bw *bandwidth
  147. once sync.Once
  148. window
  149. }
  150. func (Self *ReceiveWindow) New(mux *Mux) {
  151. // initial a window for receive
  152. Self.readOp = make(chan struct{})
  153. Self.bufQueue.New()
  154. //Self.bw = new(bandwidth)
  155. Self.element = new(ListElement)
  156. Self.maxSize = 8192
  157. Self.mux = mux
  158. Self.window.New()
  159. }
  160. func (Self *ReceiveWindow) remainingSize() (n uint32) {
  161. // receive window remaining
  162. return atomic.LoadUint32(&Self.maxSize) - Self.bufQueue.Len()
  163. }
  164. func (Self *ReceiveWindow) readSize() (n uint32) {
  165. // acknowledge the size already read
  166. return atomic.SwapUint32(&Self.readLength, 0)
  167. }
  168. func (Self *ReceiveWindow) calcSize() {
  169. // calculating maximum receive window size
  170. if Self.count == 0 {
  171. //logs.Warn("ping, bw", Self.mux.latency, Self.bw.Get())
  172. n := uint32(2 * Self.mux.latency * Self.mux.bw.Get() * 1.5 / float64(Self.mux.connMap.Size()))
  173. if n < 8192 {
  174. n = 8192
  175. }
  176. if n < Self.bufQueue.Len() {
  177. n = Self.bufQueue.Len()
  178. }
  179. // set the minimal size
  180. if n > 2*Self.maxSize {
  181. n = 2 * Self.maxSize
  182. }
  183. if n > common.MAXIMUM_WINDOW_SIZE {
  184. n = common.MAXIMUM_WINDOW_SIZE
  185. }
  186. // set the maximum size
  187. //logs.Warn("n", n)
  188. atomic.StoreUint32(&Self.maxSize, n)
  189. Self.count = -10
  190. }
  191. Self.count += 1
  192. }
  193. func (Self *ReceiveWindow) Write(buf []byte, l uint16, part bool, id int32) (err error) {
  194. if Self.closeOp {
  195. return errors.New("conn.receiveWindow: write on closed window")
  196. }
  197. element := new(ListElement)
  198. err = element.New(buf, l, part)
  199. //logs.Warn("push the buf", len(buf), l, (&element).l)
  200. if err != nil {
  201. return
  202. }
  203. Self.bufQueue.Push(element) // must push data before allow read
  204. //logs.Warn("read session calc size ", Self.maxSize)
  205. // calculating the receive window size
  206. Self.calcSize()
  207. //logs.Warn("read session calc size finish", Self.maxSize)
  208. if Self.remainingSize() == 0 {
  209. atomic.StoreUint32(&Self.windowFull, 1)
  210. //logs.Warn("window full true", Self.windowFull)
  211. }
  212. Self.mux.sendInfo(common.MUX_MSG_SEND_OK, id, Self.maxSize, Self.readSize())
  213. return nil
  214. }
  215. func (Self *ReceiveWindow) Read(p []byte, id int32) (n int, err error) {
  216. if Self.closeOp {
  217. return 0, io.EOF // receive close signal, returns eof
  218. }
  219. pOff := 0
  220. l := 0
  221. //logs.Warn("receive window read off, element.l", Self.off, Self.element.l)
  222. copyData:
  223. //Self.bw.StartRead()
  224. if Self.off == uint32(Self.element.l) {
  225. // on the first Read method invoked, Self.off and Self.element.l
  226. // both zero value
  227. Self.element, err = Self.bufQueue.Pop()
  228. // if the queue is empty, Pop method will wait until one element push
  229. // into the queue successful, or timeout.
  230. // timer start on timeout parameter is set up ,
  231. // reset to 60s if timeout and data still available
  232. Self.off = 0
  233. if err != nil {
  234. return // queue receive stop or time out, break the loop and return
  235. }
  236. //logs.Warn("pop element", Self.element.l, Self.element.part)
  237. }
  238. l = copy(p[pOff:], Self.element.buf[Self.off:Self.element.l])
  239. //Self.bw.SetCopySize(l)
  240. pOff += l
  241. Self.off += uint32(l)
  242. atomic.AddUint32(&Self.readLength, uint32(l))
  243. //logs.Warn("window read length buf len", Self.readLength, Self.bufQueue.Len())
  244. n += l
  245. l = 0
  246. //Self.bw.EndRead()
  247. if Self.off == uint32(Self.element.l) {
  248. //logs.Warn("put the element end ", string(Self.element.buf[:15]))
  249. common.WindowBuff.Put(Self.element.buf)
  250. Self.sendStatus(id)
  251. }
  252. if pOff < len(p) && Self.element.part {
  253. // element is a part of the segments, trying to fill up buf p
  254. goto copyData
  255. }
  256. return // buf p is full or all of segments in buf, return
  257. }
  258. func (Self *ReceiveWindow) sendStatus(id int32) {
  259. if Self.bufQueue.Len() == 0 {
  260. // window is full before read or empty now
  261. Self.mux.sendInfo(common.MUX_MSG_SEND_OK, id, atomic.LoadUint32(&Self.maxSize), Self.readSize())
  262. // acknowledge other side, have empty some receive window space
  263. //}
  264. }
  265. if atomic.LoadUint32(&Self.windowFull) > 0 && Self.remainingSize() > 0 {
  266. atomic.StoreUint32(&Self.windowFull, 0)
  267. Self.mux.sendInfo(common.MUX_MSG_SEND_OK, id, atomic.LoadUint32(&Self.maxSize), Self.readSize())
  268. }
  269. }
  270. func (Self *ReceiveWindow) SetTimeOut(t time.Time) {
  271. // waiting for FIFO queue Pop method
  272. Self.bufQueue.SetTimeOut(t)
  273. }
  274. func (Self *ReceiveWindow) Stop() {
  275. // queue has no more data to push, so unblock pop method
  276. Self.once.Do(Self.bufQueue.Stop)
  277. }
  278. func (Self *ReceiveWindow) CloseWindow() {
  279. Self.window.CloseWindow()
  280. Self.Stop()
  281. }
  282. type SendWindow struct {
  283. buf []byte
  284. sentLength uint32
  285. setSizeCh chan struct{}
  286. setSizeWait uint32
  287. timeout time.Time
  288. window
  289. }
  290. func (Self *SendWindow) New(mux *Mux) {
  291. Self.setSizeCh = make(chan struct{})
  292. Self.maxSize = 4096
  293. Self.mux = mux
  294. Self.window.New()
  295. }
  296. func (Self *SendWindow) SetSendBuf(buf []byte) {
  297. // send window buff from conn write method, set it to send window
  298. Self.buf = buf
  299. Self.off = 0
  300. }
  301. func (Self *SendWindow) RemainingSize() (n uint32) {
  302. return atomic.LoadUint32(&Self.maxSize) - atomic.LoadUint32(&Self.sentLength)
  303. }
  304. func (Self *SendWindow) SetSize(windowSize, readLength uint32) (closed bool) {
  305. defer func() {
  306. if recover() != nil {
  307. closed = true
  308. }
  309. }()
  310. if Self.closeOp {
  311. close(Self.setSizeCh)
  312. return true
  313. }
  314. if readLength == 0 && atomic.LoadUint32(&Self.maxSize) == windowSize {
  315. //logs.Warn("waiting for another window size")
  316. return false // waiting for receive another usable window size
  317. }
  318. //logs.Warn("set send window size to ", windowSize, readLength)
  319. Self.slide(windowSize, readLength)
  320. if Self.RemainingSize() == 0 {
  321. //logs.Warn("waiting for another window size after slide")
  322. // keep the wait status
  323. //atomic.StoreUint32(&Self.setSizeWait, 1)
  324. return false
  325. }
  326. if atomic.CompareAndSwapUint32(&Self.setSizeWait, 1, 0) {
  327. // send window into the wait status, need notice the channel
  328. select {
  329. case Self.setSizeCh <- struct{}{}:
  330. //logs.Warn("send window remaining size is 0 finish")
  331. return false
  332. case <-Self.closeOpCh:
  333. close(Self.setSizeCh)
  334. return true
  335. }
  336. }
  337. // send window not into the wait status, so just do slide
  338. return false
  339. }
  340. func (Self *SendWindow) slide(windowSize, readLength uint32) {
  341. atomic.AddUint32(&Self.sentLength, ^readLength-1)
  342. atomic.StoreUint32(&Self.maxSize, windowSize)
  343. }
  344. func (Self *SendWindow) WriteTo() (p []byte, sendSize uint32, part bool, err error) {
  345. // returns buf segments, return only one segments, need a loop outside
  346. // until err = io.EOF
  347. if Self.closeOp {
  348. return nil, 0, false, errors.New("conn.writeWindow: window closed")
  349. }
  350. if Self.off == uint32(len(Self.buf)) {
  351. return nil, 0, false, io.EOF
  352. // send window buff is drain, return eof and get another one
  353. }
  354. if Self.RemainingSize() == 0 {
  355. atomic.StoreUint32(&Self.setSizeWait, 1)
  356. // into the wait status
  357. err = Self.waitReceiveWindow()
  358. if err != nil {
  359. return nil, 0, false, err
  360. }
  361. }
  362. if len(Self.buf[Self.off:]) > common.MAXIMUM_SEGMENT_SIZE {
  363. sendSize = common.MAXIMUM_SEGMENT_SIZE
  364. //logs.Warn("cut buf by mss")
  365. } else {
  366. sendSize = uint32(len(Self.buf[Self.off:]))
  367. }
  368. if Self.RemainingSize() < sendSize {
  369. // usable window size is small than
  370. // window MAXIMUM_SEGMENT_SIZE or send buf left
  371. sendSize = Self.RemainingSize()
  372. //logs.Warn("cut buf by remainingsize", sendSize, len(Self.buf[Self.off:]))
  373. }
  374. //logs.Warn("send size", sendSize)
  375. if sendSize < uint32(len(Self.buf[Self.off:])) {
  376. part = true
  377. }
  378. p = Self.buf[Self.off : sendSize+Self.off]
  379. Self.off += sendSize
  380. atomic.AddUint32(&Self.sentLength, sendSize)
  381. return
  382. }
  383. func (Self *SendWindow) waitReceiveWindow() (err error) {
  384. t := Self.timeout.Sub(time.Now())
  385. if t < 0 {
  386. t = time.Minute
  387. }
  388. timer := time.NewTimer(t)
  389. defer timer.Stop()
  390. // waiting for receive usable window size, or timeout
  391. select {
  392. case _, ok := <-Self.setSizeCh:
  393. if !ok {
  394. return errors.New("conn.writeWindow: window closed")
  395. }
  396. return nil
  397. case <-timer.C:
  398. return errors.New("conn.writeWindow: write to time out")
  399. case <-Self.closeOpCh:
  400. return errors.New("conn.writeWindow: window closed")
  401. }
  402. }
  403. func (Self *SendWindow) WriteFull(buf []byte, id int32) (n int, err error) {
  404. Self.SetSendBuf(buf) // set the buf to send window
  405. var bufSeg []byte
  406. var part bool
  407. var l uint32
  408. for {
  409. bufSeg, l, part, err = Self.WriteTo()
  410. //logs.Warn("buf seg", len(bufSeg), part, err)
  411. // get the buf segments from send window
  412. if bufSeg == nil && part == false && err == io.EOF {
  413. // send window is drain, break the loop
  414. err = nil
  415. break
  416. }
  417. if err != nil {
  418. break
  419. }
  420. n += int(l)
  421. l = 0
  422. if part {
  423. Self.mux.sendInfo(common.MUX_NEW_MSG_PART, id, bufSeg)
  424. } else {
  425. Self.mux.sendInfo(common.MUX_NEW_MSG, id, bufSeg)
  426. //logs.Warn("buf seg sent", len(bufSeg), part, err)
  427. }
  428. // send to other side, not send nil data to other side
  429. }
  430. //logs.Warn("buf seg write success")
  431. return
  432. }
  433. func (Self *SendWindow) SetTimeOut(t time.Time) {
  434. // waiting for receive a receive window size
  435. Self.timeout = t
  436. }
  437. //type bandwidth struct {
  438. // readStart time.Time
  439. // lastReadStart time.Time
  440. // readEnd time.Time
  441. // lastReadEnd time.Time
  442. // bufLength int
  443. // lastBufLength int
  444. // count int8
  445. // readBW float64
  446. // writeBW float64
  447. // readBandwidth float64
  448. //}
  449. //
  450. //func (Self *bandwidth) StartRead() {
  451. // Self.lastReadStart, Self.readStart = Self.readStart, time.Now()
  452. // if !Self.lastReadStart.IsZero() {
  453. // if Self.count == -5 {
  454. // Self.calcBandWidth()
  455. // }
  456. // }
  457. //}
  458. //
  459. //func (Self *bandwidth) EndRead() {
  460. // Self.lastReadEnd, Self.readEnd = Self.readEnd, time.Now()
  461. // if Self.count == -5 {
  462. // Self.calcWriteBandwidth()
  463. // }
  464. // if Self.count == 0 {
  465. // Self.calcReadBandwidth()
  466. // Self.count = -6
  467. // }
  468. // Self.count += 1
  469. //}
  470. //
  471. //func (Self *bandwidth) SetCopySize(n int) {
  472. // // must be invoke between StartRead and EndRead
  473. // Self.lastBufLength, Self.bufLength = Self.bufLength, n
  474. //}
  475. //// calculating
  476. //// start end start end
  477. //// read read
  478. //// write
  479. //
  480. //func (Self *bandwidth) calcBandWidth() {
  481. // t := Self.readStart.Sub(Self.lastReadStart)
  482. // if Self.lastBufLength >= 32768 {
  483. // Self.readBandwidth = float64(Self.lastBufLength) / t.Seconds()
  484. // }
  485. //}
  486. //
  487. //func (Self *bandwidth) calcReadBandwidth() {
  488. // // Bandwidth between nps and npc
  489. // readTime := Self.readEnd.Sub(Self.readStart)
  490. // Self.readBW = float64(Self.bufLength) / readTime.Seconds()
  491. // //logs.Warn("calc read bw", Self.readBW, Self.bufLength, readTime.Seconds())
  492. //}
  493. //
  494. //func (Self *bandwidth) calcWriteBandwidth() {
  495. // // Bandwidth between nps and user, npc and application
  496. // writeTime := Self.readStart.Sub(Self.lastReadEnd)
  497. // Self.writeBW = float64(Self.lastBufLength) / writeTime.Seconds()
  498. // //logs.Warn("calc write bw", Self.writeBW, Self.bufLength, writeTime.Seconds())
  499. //}
  500. //
  501. //func (Self *bandwidth) Get() (bw float64) {
  502. // // The zero value, 0 for numeric types
  503. // if Self.writeBW == 0 && Self.readBW == 0 {
  504. // //logs.Warn("bw both 0")
  505. // return 100
  506. // }
  507. // if Self.writeBW == 0 && Self.readBW != 0 {
  508. // return Self.readBW
  509. // }
  510. // if Self.readBW == 0 && Self.writeBW != 0 {
  511. // return Self.writeBW
  512. // }
  513. // return Self.readBandwidth
  514. //}