func dial(netw, addr, svc string) (nchan.Conn, error) { switch netw { case "tcp", "tcp4", "tcp6": if auth.TLSclient == nil { taddr, err := net.ResolveTCPAddr(netw, addr+":"+svc) if err != nil { return nchan.Conn{}, err } c, err := net.DialTCP(netw, nil, taddr) if err != nil { return nchan.Conn{}, err } nc := nchan.NewConn(c, 5, nil, nil) return nc, nil } taddr, err := net.ResolveTCPAddr(netw, addr+":"+svc) if err != nil { return nchan.Conn{}, err } c, err := net.DialTCP(netw, nil, taddr) if err != nil { return nchan.Conn{}, err } // Beware this is not enough if you have NATs c.SetKeepAlivePeriod(2 * time.Second) c.SetKeepAlive(true) tc := tls.Client(c, auth.TLSclient) nc := nchan.NewConn(tc, 5, nil, nil) return nc, nil case "pipe": lk.Lock() defer lk.Unlock() dialer, ok := pipes[svc] if !ok { return nchan.Conn{}, errors.New("no such pipe") } return dialer() case "fifo": return fifo.Dial(svc) default: return nchan.Conn{}, errors.New("unknown network") } }
// Handle one client, called by net.Srv. func (h ch) HandleCli(c net.Conn, endc chan bool) { inc := make(chan bool) outc := make(chan bool) nc := nchan.NewConn(c, 5, inc, outc) nc.Tag = c.RemoteAddr().String() h.ncc <- &nc doselect { case <-inc: inc = nil if inc==nil && outc==nil { return } case <-outc: outc = nil if inc==nil && outc==nil { return } case <-endc: close(nc.In, "server closing") close(nc.Out, "server closing") c.Close() } }