io.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // +build !confonly
  2. package kcp
  3. import (
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "io"
  7. "v2ray.com/core/common"
  8. "v2ray.com/core/common/buf"
  9. "v2ray.com/core/transport/internet"
  10. )
  11. type PacketReader interface {
  12. Read([]byte) []Segment
  13. }
  14. type PacketWriter interface {
  15. Overhead() int
  16. io.Writer
  17. }
  18. type KCPPacketReader struct { // nolint: golint
  19. Security cipher.AEAD
  20. Header internet.PacketHeader
  21. }
  22. func (r *KCPPacketReader) Read(b []byte) []Segment {
  23. if r.Header != nil {
  24. if int32(len(b)) <= r.Header.Size() {
  25. return nil
  26. }
  27. b = b[r.Header.Size():]
  28. }
  29. if r.Security != nil {
  30. nonceSize := r.Security.NonceSize()
  31. overhead := r.Security.Overhead()
  32. if len(b) <= nonceSize+overhead {
  33. return nil
  34. }
  35. out, err := r.Security.Open(b[nonceSize:nonceSize], b[:nonceSize], b[nonceSize:], nil)
  36. if err != nil {
  37. return nil
  38. }
  39. b = out
  40. }
  41. var result []Segment
  42. for len(b) > 0 {
  43. seg, x := ReadSegment(b)
  44. if seg == nil {
  45. break
  46. }
  47. result = append(result, seg)
  48. b = x
  49. }
  50. return result
  51. }
  52. type KCPPacketWriter struct { // nolint: golint
  53. Header internet.PacketHeader
  54. Security cipher.AEAD
  55. Writer io.Writer
  56. }
  57. func (w *KCPPacketWriter) Overhead() int {
  58. overhead := 0
  59. if w.Header != nil {
  60. overhead += int(w.Header.Size())
  61. }
  62. if w.Security != nil {
  63. overhead += w.Security.Overhead()
  64. }
  65. return overhead
  66. }
  67. func (w *KCPPacketWriter) Write(b []byte) (int, error) {
  68. bb := buf.StackNew()
  69. defer bb.Release()
  70. if w.Header != nil {
  71. w.Header.Serialize(bb.Extend(w.Header.Size()))
  72. }
  73. if w.Security != nil {
  74. nonceSize := w.Security.NonceSize()
  75. common.Must2(bb.ReadFullFrom(rand.Reader, int32(nonceSize)))
  76. nonce := bb.BytesFrom(int32(-nonceSize))
  77. encrypted := bb.Extend(int32(w.Security.Overhead() + len(b)))
  78. w.Security.Seal(encrypted[:0], nonce, b, nil)
  79. } else {
  80. bb.Write(b)
  81. }
  82. _, err := w.Writer.Write(bb.Bytes())
  83. return len(b), err
  84. }