FrameStreamSockInput.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * Copyright (c) 2013-2019 by Farsight Security, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package dnstap
  17. import (
  18. "fmt"
  19. "net"
  20. "os"
  21. "time"
  22. )
  23. // A FrameStreamSockInput collects dnstap data from one or more clients of
  24. // a listening socket.
  25. type FrameStreamSockInput struct {
  26. wait chan bool
  27. listener net.Listener
  28. timeout time.Duration
  29. log Logger
  30. }
  31. // NewFrameStreamSockInput creates a FrameStreamSockInput collecting dnstap
  32. // data from clients which connect to the given listener.
  33. func NewFrameStreamSockInput(listener net.Listener) (input *FrameStreamSockInput) {
  34. input = new(FrameStreamSockInput)
  35. input.listener = listener
  36. input.log = &nullLogger{}
  37. return
  38. }
  39. // SetTimeout sets the timeout for reading the initial handshake and writing
  40. // response control messages to clients of the FrameStreamSockInput's listener.
  41. //
  42. // The timeout is effective only for connections accepted after the call to
  43. // SetTimeout.
  44. func (input *FrameStreamSockInput) SetTimeout(timeout time.Duration) {
  45. input.timeout = timeout
  46. }
  47. // SetLogger configures a logger for the FrameStreamSockInput.
  48. func (input *FrameStreamSockInput) SetLogger(logger Logger) {
  49. input.log = logger
  50. }
  51. // NewFrameStreamSockInputFromPath creates a unix domain socket at the
  52. // given socketPath and returns a FrameStreamSockInput collecting dnstap
  53. // data from clients connecting to this socket.
  54. //
  55. // If a socket or other file already exists at socketPath,
  56. // NewFrameStreamSockInputFromPath removes it before creating the socket.
  57. func NewFrameStreamSockInputFromPath(socketPath string) (input *FrameStreamSockInput, err error) {
  58. os.Remove(socketPath)
  59. listener, err := net.Listen("unix", socketPath)
  60. if err != nil {
  61. return
  62. }
  63. return NewFrameStreamSockInput(listener), nil
  64. }
  65. // ReadInto accepts connections to the FrameStreamSockInput's listening
  66. // socket and sends all dnstap data read from these connections to the
  67. // output channel.
  68. //
  69. // ReadInto satisfies the dnstap Input interface.
  70. func (input *FrameStreamSockInput) ReadInto(output chan []byte) {
  71. var n uint64
  72. for {
  73. conn, err := input.listener.Accept()
  74. if err != nil {
  75. input.log.Printf("%s: accept failed: %v\n",
  76. input.listener.Addr(),
  77. err)
  78. continue
  79. }
  80. n++
  81. origin := ""
  82. switch conn.RemoteAddr().Network() {
  83. case "tcp", "tcp4", "tcp6":
  84. origin = fmt.Sprintf(" from %s", conn.RemoteAddr())
  85. }
  86. i, err := NewFrameStreamInputTimeout(conn, true, input.timeout)
  87. if err != nil {
  88. input.log.Printf("%s: connection %d: open input%s failed: %v",
  89. conn.LocalAddr(), n, origin, err)
  90. continue
  91. }
  92. input.log.Printf("%s: accepted connection %d%s",
  93. conn.LocalAddr(), n, origin)
  94. i.SetLogger(input.log)
  95. go func(cn uint64) {
  96. i.ReadInto(output)
  97. input.log.Printf("%s: closed connection %d%s",
  98. conn.LocalAddr(), cn, origin)
  99. }(n)
  100. }
  101. }
  102. // Wait satisfies the dnstap Input interface.
  103. //
  104. // The FrameSTreamSocketInput Wait method never returns, because the
  105. // corresponding Readinto method also never returns.
  106. func (input *FrameStreamSockInput) Wait() {
  107. select {}
  108. }