func (connection *connection) pipeOutput() { for { select { case message, ok := <-connection.parsedMessages: if ok { log.Debug("Connection %p from %s to %s received message over the wire: %s", connection, connection.baseConn.RemoteAddr(), connection.baseConn.LocalAddr(), message.Short()) connection.output <- message } else { break } case err, ok := <-connection.parserErrors: if ok { // The parser has hit a terminal error. We need to restart it. log.Warn("Failed to parse SIP message: %s", err.Error()) connection.parser = parser.NewParser(connection.parsedMessages, connection.parserErrors, connection.isStreamed) } else { break } } } log.Info("Parser stopped in ConnWrapper %v (local addr %s; remote addr %s); stopping listening", connection, connection.baseConn.LocalAddr(), connection.baseConn.RemoteAddr()) }
func NewConn(baseConn net.Conn, output chan base.SipMessage) *connection { var isStreamed bool switch baseConn.(type) { case *net.UDPConn: isStreamed = false case *net.TCPConn: isStreamed = true case *tls.Conn: isStreamed = true default: log.Severe("Conn object %v is not a known connection type. Assume it's a streamed protocol, but this may cause messages to be rejected") } connection := connection{baseConn: baseConn, isStreamed: isStreamed} connection.parsedMessages = make(chan base.SipMessage) connection.parserErrors = make(chan error) connection.output = output connection.parser = parser.NewParser(connection.parsedMessages, connection.parserErrors, connection.isStreamed) go connection.read() go connection.pipeOutput() return &connection }
// Construct a dummy connection object to use to populate the connTable for tests. func makeTestConn() *connection { parsedMessages := make(chan base.SipMessage) errors := make(chan error) streamed := true return &connection{ &testutils.DummyConn{}, true, parser.NewParser(parsedMessages, errors, streamed), parsedMessages, errors, make(chan base.SipMessage), } }