1package srslog 2 3import ( 4 "crypto/tls" 5 "net" 6) 7 8// dialerFunctionWrapper is a simple object that consists of a dialer function 9// and its name. This is primarily for testing, so we can make sure that the 10// getDialer method returns the correct dialer function. However, if you ever 11// find that you need to check which dialer function you have, this would also 12// be useful for you without having to use reflection. 13type dialerFunctionWrapper struct { 14 Name string 15 Dialer func() (serverConn, string, error) 16} 17 18// Call the wrapped dialer function and return its return values. 19func (df dialerFunctionWrapper) Call() (serverConn, string, error) { 20 return df.Dialer() 21} 22 23// getDialer returns a "dialer" function that can be called to connect to a 24// syslog server. 25// 26// Each dialer function is responsible for dialing the remote host and returns 27// a serverConn, the hostname (or a default if the Writer has not specified a 28// hostname), and an error in case dialing fails. 29// 30// The reason for separate dialers is that different network types may need 31// to dial their connection differently, yet still provide a net.Conn interface 32// that you can use once they have dialed. Rather than an increasingly long 33// conditional, we have a map of network -> dialer function (with a sane default 34// value), and adding a new network type is as easy as writing the dialer 35// function and adding it to the map. 36func (w *Writer) getDialer() dialerFunctionWrapper { 37 dialers := map[string]dialerFunctionWrapper{ 38 "": dialerFunctionWrapper{"unixDialer", w.unixDialer}, 39 "tcp+tls": dialerFunctionWrapper{"tlsDialer", w.tlsDialer}, 40 } 41 dialer, ok := dialers[w.network] 42 if !ok { 43 dialer = dialerFunctionWrapper{"basicDialer", w.basicDialer} 44 } 45 return dialer 46} 47 48// unixDialer uses the unixSyslog method to open a connection to the syslog 49// daemon running on the local machine. 50func (w *Writer) unixDialer() (serverConn, string, error) { 51 sc, err := unixSyslog() 52 hostname := w.hostname 53 if hostname == "" { 54 hostname = "localhost" 55 } 56 return sc, hostname, err 57} 58 59// tlsDialer connects to TLS over TCP, and is used for the "tcp+tls" network 60// type. 61func (w *Writer) tlsDialer() (serverConn, string, error) { 62 c, err := tls.Dial("tcp", w.raddr, w.tlsConfig) 63 var sc serverConn 64 hostname := w.hostname 65 if err == nil { 66 sc = &netConn{conn: c} 67 if hostname == "" { 68 hostname = c.LocalAddr().String() 69 } 70 } 71 return sc, hostname, err 72} 73 74// basicDialer is the most common dialer for syslog, and supports both TCP and 75// UDP connections. 76func (w *Writer) basicDialer() (serverConn, string, error) { 77 c, err := net.Dial(w.network, w.raddr) 78 var sc serverConn 79 hostname := w.hostname 80 if err == nil { 81 sc = &netConn{conn: c} 82 if hostname == "" { 83 hostname = c.LocalAddr().String() 84 } 85 } 86 return sc, hostname, err 87} 88