padding_null.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // padding_null.go - Null padding implementation.
  2. // Copyright (C) 2016 Yawning Angel.
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Affero General Public License as
  6. // published by the Free Software Foundation, either version 3 of the
  7. // License, or (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Affero General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Affero General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. package basket2
  17. import (
  18. "bytes"
  19. "git.schwanenlied.me/yawning/basket2.git/framing"
  20. "git.schwanenlied.me/yawning/basket2.git/framing/tentp"
  21. )
  22. const (
  23. // PaddingNull is the "NULL" padding algorithm. No packet length or
  24. // timing obfuscation will be done beyond the standard handshake
  25. // obfuscation. This method SHOULD NOT currently be used, and is only
  26. // provided for testing, and in anticipation of Tor getting it's own
  27. // circuit level padding implementation.
  28. PaddingNull PaddingMethod = 0
  29. )
  30. type nullPadding struct {
  31. conn *commonConn
  32. recvBuf bytes.Buffer
  33. }
  34. func (p *nullPadding) Write(b []byte) (int, error) {
  35. // Break the write up into records, and send them out on the wire. The
  36. // kernel is better at breaking writes into appropriate sized packets than
  37. // any userland app will be (at least with TCP), so use the maximum record
  38. // size permitted by the framing layer as padding isn't a concern.
  39. for off, left := 0, len(b); left > 0; {
  40. wrSize := tentp.MaxPlaintextRecordSize
  41. if left < wrSize {
  42. wrSize = left
  43. }
  44. if err := p.conn.SendRawRecord(framing.CmdData, b[off:off+wrSize], 0); err != nil {
  45. return 0, err
  46. }
  47. off += wrSize
  48. left -= wrSize
  49. }
  50. return len(b), nil
  51. }
  52. func (p *nullPadding) Read(b []byte) (n int, err error) {
  53. return paddingImplGenericRead(p.conn, &p.recvBuf, b)
  54. }
  55. func (p *nullPadding) OnClose() {
  56. p.recvBuf.Reset()
  57. }
  58. func newNullPadding(conn *commonConn) paddingImpl {
  59. p := new(nullPadding)
  60. p.conn = conn
  61. // The net package default beahvior is to disable Nagle's algorithm,
  62. // but it's more efficient to enable it, since the kernel will handle
  63. // framing better than we can, especially for this use case.
  64. conn.setNagle(true)
  65. return p
  66. }