コード例 #1
0
ファイル: proto-cli.go プロジェクト: fcavani/gormethods
func (s *protoSession) recv(val interface{}) error {
	if s.status != connected {
		return e.New(ErrNoConn)
	}
	if s.connTimeout > 0 {
		err := s.conn.SetReadDeadline(time.Now().Add(s.connTimeout))
		if err != nil {
			log.ProtoLevel().Tag("gormethods", "client", "proto").Printf("Send: deadline error: %v", err)
			s.status = reconnect
			return e.Forward(err)
		}
	}
	dec := msgpack.NewDecoder(s.conn)
	err := dec.Decode(val)
	if err != nil {
		s.status = reconnect
		log.ProtoLevel().Tag("gormethods", "client", "proto").Printf("Recv: connect error: %v", err)
		s.conn.SetReadDeadline(time.Time{})
		return e.Forward(err)
	}
	err = s.conn.SetReadDeadline(time.Time{})
	if err != nil {
		log.ProtoLevel().Tag("gormethods", "client", "proto").Printf("Send: deadline error: %v", err)
		s.status = reconnect
		return e.Forward(err)
	}
	return nil
}
コード例 #2
0
ファイル: clone.go プロジェクト: fcavani/gormethods
func (c *clone) Init(inst string) error {
	if c.Num <= 0 {
		return e.New("number of clones invalid")
	}
	if c.Session == nil {
		return e.New("nil Session")
	}
	if c.Num > c.MaxNum {
		return e.New("number of initial streams is greater than the maximun")
	}
	c.inst = inst
	c.once.Do(func() {
		c.conns = make([]connInst, 0, c.Num)
		log.ProtoLevel().Tag("gormethods", "client", "clone").Println("Init clones.")
		for i := 0; i < c.Num; i++ {
			conn, err := c.Session.NamedInstance(c.inst)
			if err != nil {
				log.ProtoLevel().Tag("gormethods", "client", "clone").Printf("New instance failed: %v.", err)
				continue
			}
			c.conns = append(c.conns, conn)
		}
	})
	return nil
}
コード例 #3
0
ファイル: proto-cli.go プロジェクト: fcavani/gormethods
func (p *protoSession) sortIncoming() {
	go func() {
		defer func() {
			log.ProtoLevel().Tag("gormethods", "client", "proto").Println("Stopping sorting income data.")
			p.closed <- struct{}{}
		}()
	F:
		for {
			const SleepReconect = 10 * time.Second
			err := p.connect()
			if err != nil {
				log.Tag("gormethods", "client", "proto").Errorf("Connect error: %v", err)
				p.bufs.ErrorAll(e.Forward(err))
				time.Sleep(SleepReconect)
				continue F
			}
			err = sortIncoming(p.reader, p.bufs, "client")
			if err != nil {
				p.lckConn.Lock()
				status := p.status
				p.lckConn.Unlock()
				log.ProtoLevel().Tag("gormethods", "client", "proto").Printf("Stopping income data. Status: %v", status)
				if status == dontreconnect || status == closed {
					break F
				}
				log.Tag("gormethods", "client", "proto").Errorf("Parsing incoming data from %v to %v failed: %v", p.conn.LocalAddr(), p.conn.RemoteAddr(), e.Trace(e.Forward(err)))
				p.invConn()
				p.bufs.ErrorAll(e.Forward(err))
				time.Sleep(SleepReconect)
				continue F
			}
			time.Sleep(SleepReconect)
		}
	}()
}
コード例 #4
0
ファイル: proto-cli.go プロジェクト: fcavani/gormethods
func (s *protoSession) connect() error {
	s.lckConn.Lock()
	defer s.lckConn.Unlock()
	var err error
	if s.status == connected {
		return nil
	}
	if s.status == dontreconnect {
		return e.New("can't reconect any more")
	}
	s.status = reconnect
	op := func() (bool, error) {
		var err error
		if s.tlsConfig == nil {
			s.conn, err = net.DialTimeout(s.proto, s.addr, s.dialTimeout)
		} else {
			s.conn, err = tls.DialWithDialer((&net.Dialer{Timeout: s.dialTimeout}), s.proto, s.addr, s.tlsConfig)
		}
		if e.Contains(err, "too many open files") {
			log.ProtoLevel().Tag("gormethods", "client", "proto").Printf("Dial error: %v", err)
			s.status = dontreconnect
			return false, e.Forward(err)
		} else if err != nil {
			log.ProtoLevel().Tag("gormethods", "client", "proto").Printf("Dial error: %v", err)
			return true, e.Forward(err)
		}
		return false, nil
	}
	exp := backoff.NewExponentialBackOff()
	err = backoff.Retry(op, exp)
	if err != nil {
		return e.Forward(err)
	}

	s.status = connected

	err = s.send(&ProtoAuth{
		Auth:         s.auth,
		Sess:         s.sess,
		ProtoVersion: ProtoVersion,
	})
	var resp ErrResp
	err = s.recv(&resp)
	if err != nil {
		return e.Forward(err)
	}
	if resp.Err != nil {
		return e.Forward(resp.Err)
	}
	//log.Tag("gormethods", "client", "proto").Printf("Connected to %v.", s.conn.RemoteAddr())
	s.reader = bufio.NewReader(s.conn)
	return nil
}
コード例 #5
0
ファイル: barrier.go プロジェクト: fcavani/gormethods
//Close the associated gorotine and all queued wait channels.
func (b *Barrier) Close() {
	if b.isclosed {
		return
	}
	if <-b.chIsShutdown {
		log.ProtoLevel().Tag("gormethods", "barrier").Printf("barrier shutdown requested, ignore close.")
		return
	}
	ch := make(chan struct{})
	b.chclose <- ch
	//close(b.chclose)
	<-ch
	log.ProtoLevel().Tag("gormethods", "barrier").Printf("barrier close ok, chan returned")
}
コード例 #6
0
ファイル: clone.go プロジェクト: fcavani/gormethods
func (c *clone) Return(conn connInst) error {
	c.lck.Lock()
	defer c.lck.Unlock()
	if len(c.conns) >= c.MaxNum {
		err := conn.Close()
		if err != nil {
			return e.Forward(err)
		}
		log.ProtoLevel().Tag("gormethods", "client", "clone").Println("Pool is full, discart.")
		return nil
	}
	log.ProtoLevel().Tag("gormethods", "client", "clone").Println("Put clone back in the pool.")
	c.conns = append(c.conns, conn)
	return nil
}
コード例 #7
0
ファイル: client.go プロジェクト: fcavani/discover
func (c *Client) response() (*Response, error) {
	log.ProtoLevel().Tag("client", "discover").Printf("Waiting response...")
	buf := make([]byte, c.BufSize)
	err := c.conn.SetDeadline(time.Now().Add(c.Deadline))
	if err != nil {
		return nil, e.New(err)
	}
	n, addr, err := c.conn.ReadFromUDP(buf)
	if err != nil {
		return nil, e.New(err)
	}
	log.ProtoLevel().Tag("client", "discover").Printf("Response from %v with size %v.", addr, n)
	err = c.conn.SetDeadline(time.Time{})
	if err != nil {
		return nil, e.New(err)
	}

	dec := gob.NewDecoder(bytes.NewReader(buf[:n]))
	var msg Msg
	err = dec.Decode(&msg)
	if err != nil {
		return nil, e.Push(err, e.New("error decoding response"))
	}

	if msg.Err != nil {
		return nil, e.Forward(msg.Err)
	}

	if msg.From != c.ServerName {
		return nil, e.New("wrong server name")
	}
	if msg.To != c.Name {
		return nil, e.New("message isn't for me")
	}

	buf, err = msg.Message(c.ServerKey, c.PrivateKey)
	if err != nil {
		return nil, e.Push(err, e.New("error decrypting response"))
	}

	dec = gob.NewDecoder(bytes.NewReader(buf))
	var resp Response
	err = dec.Decode(&resp)
	if err != nil {
		return nil, e.Push(err, e.New("error decoding response"))
	}
	return &resp, nil
}
コード例 #8
0
ファイル: client.go プロジェクト: fcavani/gormethods
func (c *client) Init() error {
	var err error
	c.session, err = openSession(c.Proto, c.Addr, c.TlsConfig, c.SessionName, c.Auth, c.DialTimeout, c.ConnTimeout)
	if err != nil {
		return e.Forward(err)
	}
	c.clones = &clones{
		Num:    c.NumClones,
		MaxNum: c.MaxNumClones,
	}
	err = c.clones.Init()
	if err != nil {
		return e.Forward(err)
	}
	if c.KeepAlive == 0 {
		return nil
	}
	go func() {
		for {
			time.Sleep(c.KeepAlive)
			err := c.session.Keepalive()
			if err != nil {
				log.ProtoLevel().Tag("gormethods", "client", "keepalive").Printf("Keepalive failed: %v", err)
			}
		}
	}()
	return nil
}
コード例 #9
0
ファイル: proto-server.go プロジェクト: fcavani/gormethods
func writeError(s *servStreams, num uint32, err error) {
	log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't write new stream reponse for %v: %v", s.conn.RemoteAddr(), err)
	if num != 0 && num != keepAliveStream {
		err = s.streams.Deactivate(num)
		if err != nil {
			log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't deactivate stream %v: %v", num, err)
		}
		err = s.bufs.Delete(num)
		if err != nil {
			log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't delete stream %v: %v", num, err)
		}
	}
	s.acceptFifo <- &newAccept{
		err: e.New(ErrStreamClosed),
	}
}
コード例 #10
0
ファイル: clone.go プロジェクト: fcavani/gormethods
func (c *clone) Request() (connInst, error) {
	c.lck.Lock()
	defer c.lck.Unlock()
	if len(c.conns) <= 0 {
		conn, err := c.Session.NamedInstance(c.inst)
		if err != nil {
			return nil, e.Forward(err)
		}
		log.ProtoLevel().Tag("gormethods", "client", "clone").Println("Pool is empty, creating another clone.")
		return conn, nil
	}
	clone := c.conns[len(c.conns)-1]
	c.conns = c.conns[:len(c.conns)-1]
	log.ProtoLevel().Tag("gormethods", "client", "clone").Println("Get object from pool.", len(c.conns))
	return clone, nil
}
コード例 #11
0
ファイル: http.go プロジェクト: fcavani/ping
// PingHttp connect a http or https server and try to
// receive something. If the server return a code different
// of 2xx, it will fail. Ignores insecure certificates.
func PingHttp(url *url.URL) error {
	resp, err := httpClient.Get(url.String())
	if e.Contains(err, "connection refused") {
		return e.Push(e.New(err), "get failed: connection refused")
	} else if err != nil {
		return e.Push(e.New(err), "get failed")
	}
	defer resp.Body.Close()
	buf := make([]byte, 4096)
	if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
		n, err := resp.Body.Read(buf)
		if err != nil && err != io.EOF {
			return e.Forward(err)
		}
		buf = buf[:n]
		//status.Log(status.Protocol, "PingHttp status code is %v and received it from server: %v", resp.StatusCode, string(buf))
		log.ProtoLevel().Printf("PingHttp status code is %v and received it from server: %v", resp.StatusCode, string(buf))
		return e.New("returned status code %v, expected 2xx", resp.StatusCode)
	}
	_, err = resp.Body.Read(buf)
	if err != nil && err != io.EOF {
		return e.Forward(err)
	}
	return nil
}
コード例 #12
0
ファイル: proto-server.go プロジェクト: fcavani/gormethods
func newServStreams(conn net.Conn, session string, auth auth.Auth, p *protoServer) (*servStreams, error) {
	s := &servStreams{
		p:           p,
		conn:        conn,
		bufs:        newBuffers(numBuffers),
		streams:     newActiveStreams(),
		acceptFifo:  make(chan *newAccept, p.FifoLength),
		session:     session,
		auth:        auth,
		streamCount: 1,
	}
	reader := bufio.NewReader(s.conn)
	go func() {
		defer func() {
			s.acceptFifo <- &newAccept{
				err: e.New(ErrStreamClosed),
			}
			log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Stop sort incoming.")
		}()
		for {
			err := sortIncoming(reader, s.bufs, "server")
			if e.Equal(err, ErrNetwork) || err == nil {
				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("sortIncoming stoped with isclose = %v and error: %v", s.isclose, err)
				s.lck.Lock()
				if s.isclose {
					s.lck.Unlock()
					return
				}
				s.isclose = true
				s.bufs.ErrorAll(e.New("conn close"))
				s.bufs.ReqShutdownAll()
				s.lck.Unlock()
				return
			} else if err != nil {
				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("sortIncoming failed: %v", err)
				continue
			}
		}
	}()
	s.zero()
	s.keepalive()
	return s, nil
}
コード例 #13
0
ファイル: server.go プロジェクト: fcavani/gormethods
func (s *Server) protocol(conn InstConn) error {
	dec := conn.Decoder()
	defer func() {
		num := conn.StreamNum()
		s.lck.Lock()
		if _, found := s.connections[num]; found {
			delete(s.connections, num)
		}
		s.lck.Unlock()
		conn.Close()
		log.DebugLevel().Tag("server", "gormethods", "protocol").Println("protocol close")
	}()
	for {
		s.lck.Lock()
		connection, found := s.connections[conn.StreamNum()]
		if !found {
			connection = &Connection{}
			s.connections[conn.StreamNum()] = connection
		}
		connection.ttl = time.Now().Add(s.Ttl)
		connection.conn = conn
		s.lck.Unlock()
		var req msgtypes.MessageType
		// se fechar a conn do outro lado deve acontecer um err aqui
		err := dec.Decode(&req)
		if e.Find(err, io.EOF) >= 0 {
			return e.Forward(err)
		} else if err != nil {
			log.DebugLevel().Tag("server", "gormethods").Printf("Decode %v -> %v (%v) error: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), e.Trace(e.Forward(err)))
			return e.Forward(err)
		}
		switch req {
		case msgtypes.Call:
			err = s.protoCall(conn)
			if e.Find(err, ErrWire) >= 0 {
				return e.Forward(err)
			}
		case msgtypes.Destroy:
			err = s.protoDestroy(conn)
			if e.Find(err, ErrWire) >= 0 {
				return e.Forward(err)
			}
			return nil
		case msgtypes.Channel:
			err = s.protoChannel(conn)
			if e.Find(err, ErrWire) >= 0 {
				return e.Forward(err)
			}
			return nil
		default:
			log.ProtoLevel().Tag("server", "gormethods").Printf("Protocol fail from %v -> %v (%v) sent: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), req)
		}
	}
}
コード例 #14
0
ファイル: client.go プロジェクト: fcavani/gormethods
func finalizer(client ClientInt) {
	log.ProtoLevel().Tag("gormethods", "client").Printf("Finalize %v, %v", client.SessionName(), client.InstanceName())
	err := client.Destroy()
	if err != nil {
		log.Error("Client finalizer failed:", err)
	}
	err = client.CloseClient()
	if err != nil {
		log.Error("Client finalizer failed:", err)
	}
}
コード例 #15
0
ファイル: proto-server.go プロジェクト: fcavani/gormethods
func (s *servStreams) keepalive() {
	go func() {
		defer func() {
			log.ProtoLevel().Tag("gormethods", "server", "proto").Println("Stop keepalive.")
		}()
		buf := make([]byte, payloadSize)
		for {
			n, err := s.bufs.Read(keepAliveStream, buf)
			if err != nil {
				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't read from stream %v: %v", keepAliveStream, err)
				break
			}
			if n != payloadSize {
				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Not enougth data from stream %v", keepAliveStream)
				continue
			}
			cmd, _, err := parseCmd(buf)
			if err != nil {
				continue
			}
			switch cmd {
			case keepAlive:
				buf := newStreamResponse(ok, keepAliveStream)
				for count := 0; count < len(buf); {
					n, err := s.write(keepAliveStream, buf[count:])
					if e.Equal(err, ErrNetwork) {
						writeError(s, keepAliveStream, e.Forward(err))
						return
					} else if err != nil {
						writeError(s, keepAliveStream, e.Forward(err))
						break
					}
					count += n
				}
			default:
				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Protocol error on stream %v: %v", keepAliveStream, cmd)
				continue
			}
		}
	}()
}
コード例 #16
0
ファイル: clone.go プロジェクト: fcavani/gormethods
func (c *clone) Close() (err error) {
	c.lck.Lock()
	defer c.lck.Unlock()
	log.ProtoLevel().Tag("gormethods", "client", "clone").Println("Close clone.")
	for _, clone := range c.conns {
		er := clone.Close()
		if er != nil {
			err = e.Push(err, e.Forward(er))
		}
	}
	return
}
コード例 #17
0
ファイル: client.go プロジェクト: fcavani/discover
func (c *Client) encode(typ msgType, val interface{}, dst *net.UDPAddr) error {
	log.ProtoLevel().Tag("client", "discover").Printf("Send request (%v) to %v from %v.", typ, dst, c.conn.LocalAddr())

	reqBuf := bytes.NewBuffer([]byte{})

	buf := make([]byte, binary.MaxVarintLen16)
	binary.PutUvarint(buf, uint64(typ))
	n, err := reqBuf.Write(buf)
	if err != nil {
		return e.Push(err, "error enconding message type")
	}
	if n != len(buf) {
		return e.Push(err, "error enconding message type")
	}

	enc := gob.NewEncoder(reqBuf)
	err = enc.Encode(val)
	if err != nil {
		return e.Push(err, e.New("error encoding"))
	}

	msg, err := NewMsg(c.Name, c.ServerName, c.PrivateKey, c.ServerKey, reqBuf.Bytes())
	if err != nil {
		return e.Push(err, "erro cryptographing the value")
	}

	reqBuf = bytes.NewBuffer([]byte{})
	enc = gob.NewEncoder(reqBuf)
	err = enc.Encode(msg)
	if err != nil {
		return e.Push(err, e.New("error encoding"))
	}

	if reqBuf.Len() > c.BufSize {
		return e.New("value to encode is too big %v", reqBuf.Len())
	}
	err = c.conn.SetDeadline(time.Now().Add(c.Deadline))
	if err != nil {
		return e.New(err)
	}
	_, _, err = c.conn.WriteMsgUDP(reqBuf.Bytes(), nil, dst)
	if err != nil {
		return e.New(err)
	}
	err = c.conn.SetDeadline(time.Time{})
	if err != nil {
		return e.New(err)
	}
	return nil
}
コード例 #18
0
ファイル: server.go プロジェクト: fcavani/gormethods
func (s *Server) protoDestroy(conn InstConn) (err error) {
	defer func() {
		if err != nil {
			err = conn.Encoder().Encode(&respErr{Err: err})
			if err != nil {
				log.ProtoLevel().Tag("server", "gormethods").Printf("Encode %v -> %v (%v) error: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), err)
				err = e.Push(err, ErrWire)
			}
		}
	}()
	err = s.Insts.Delete(conn.SessionName(), conn.InstanceName())
	if err != nil && !e.Contains(err, "instance not found") {
		log.Tag("server", "gormethods").Errorf("Can't remove the instance %v/%v: %v", conn.SessionName(), conn.InstanceName(), e.Forward(err))
		err = e.Forward(err)
		return
	}
	err = conn.Encoder().Encode(&respErr{Err: nil})
	if err != nil {
		log.ProtoLevel().Tag("server", "gormethods").Printf("Encode %v -> %v (%v) error: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), e.Forward(err))
		err = e.Push(err, ErrWire)
	}
	return
}
コード例 #19
0
ファイル: proto-cli.go プロジェクト: fcavani/gormethods
func (p *protoSession) Close() error {
	p.lckConn.Lock()
	p.status = closed
	err := p.conn.Close()
	if err != nil {
		p.lckConn.Unlock()
		return e.Forward(err)
	}
	p.lckConn.Unlock()
	//p.bufs.ErrorAll(e.New("conn close"))
	p.bufs.DeleteAll()
	//<-p.closed
	log.ProtoLevel().Tag("gormethods", "client", "proto").Print("Client conn close.")
	return nil
}
コード例 #20
0
ファイル: server.go プロジェクト: fcavani/discover
func (a *Server) sendResp(resp *Response, to string, tokey *rsa.PublicKey, addr *net.UDPAddr) {
	log.ProtoLevel().Tag("server", "discover").Printf("Send response from %v to %v", a.conn.LocalAddr(), addr)
	respBuf := bytes.NewBuffer([]byte{})
	enc := gob.NewEncoder(respBuf)
	err := enc.Encode(resp)
	if err != nil {
		log.Tag("discover", "server").Printf("Server - Protocol fail for %v with error: %v", addr, e.Trace(e.New(err)))
		a.sendErr(addr, e.Push(err, e.New("error enconding response")))
		return
	}

	msg, err := NewMsg(a.Name, to, a.PrivateKey, tokey, respBuf.Bytes())
	if err != nil {
		log.Tag("discover", "server").Printf("Server - Protocol fail for %v with error: %v", addr, e.Trace(e.New(err)))
		a.sendErr(addr, e.Push(err, e.New("error creating new response message")))
		return
	}

	respBuf = bytes.NewBuffer([]byte{})
	enc = gob.NewEncoder(respBuf)
	err = enc.Encode(msg)
	if err != nil {
		log.Tag("discover", "server").Printf("Server - Protocol fail for %v with error: %v", addr, e.Trace(e.New(err)))
		a.sendErr(addr, e.Push(err, e.New("error enconding response")))
		return
	}

	if respBuf.Len() > a.BufSize {
		log.Tag("discover", "server").Printf("Server - Protocol fail for %v message is too big (%v).", addr, respBuf.Len())
		a.sendErr(addr, e.Push(err, e.New("response is too long %v", respBuf.Len())))
		return
	}
	n, oob, err := a.conn.WriteMsgUDP(respBuf.Bytes(), nil, addr)
	if e.Contains(err, "use of closed network connection") {
		return
	} else if err != nil {
		log.Tag("discover", "server").Printf("Server - WriteMsgUDP (%v) failed: %v", addr, e.Trace(e.New(err)))
		return
	}
	if oob != 0 {
		log.Tag("discover", "server").Printf("Server - WriteMsgUDP to %v failed: %v, %v", addr, n, oob)
		return
	}
	if n != respBuf.Len() {
		log.Tag("discover", "server").Printf("Server - WriteMsgUDP to %v failed: %v, %v", addr, n, oob)
		return
	}
}
コード例 #21
0
ファイル: watchdog.go プロジェクト: fcavani/systemd
// Watchdog setup the watchdog and start then. This functoin will
// comunicate with systemd sending the pings to it, if this fails
// to send the ping systemd will reatart this daemon.
func Watchdog() (stop chan struct{}, err error) {
	// Check if systemd exist.
	if !util.IsRunningSystemd() {
		return nil, e.New(ErrNotRunning)
	}
	// Get the periode and check if watchdog is on for this daemon
	wPeriodeµsec := os.Getenv("WATCHDOG_USEC")
	if wPeriodeµsec == "" {
		return nil, e.New(ErrNoWatchdog)
	}
	wPerInt64, err := strconv.ParseInt(wPeriodeµsec, 10, 32)
	if err != nil {
		return nil, e.Push(err, ErrInvPeriode)
	}
	wPerHalf := time.Duration(int(wPerInt64)/2) * time.Microsecond
	if wPerHalf <= 0 {
		return nil, e.New(ErrInvInterval)
	}
	log.Tag("systemd", "watchdog").Printf("Starting the watchdog with interval of %v.", wPerHalf)
	stop = make(chan struct{})
	// Start the periodic pings
	go func() {
		for {
			select {
			case <-stop:
				log.Tag("systemd", "watchdog").Println("By request watchdog is stoping.")
				return
			case <-time.After(wPerHalf):
				// Send the ping.
				log.ProtoLevel().Tag("systemd", "watchdog").Println("Ping.")
				daemon.SdNotify(sdState)
			}
		}
	}()
	return
}
コード例 #22
0
ファイル: client.go プロジェクト: fcavani/discover
func (c *Client) client(addr string) (*Response, error) {
	ip, err := ipport(c.Interface, addr, "0")
	if err != nil {
		return nil, e.Push(err, ErrCantFindInt)
	}
	client, err := net.ResolveUDPAddr("udp", ip)
	if err != nil {
		return nil, e.Push(err, ErrCantFindInt)
	}
	c.conn, err = net.ListenUDP("udp", client)
	if err != nil {
		return nil, e.Push(err, ErrCantFindInt)
	}
	var dst *net.UDPAddr
	if c.iface.Flags&net.FlagLoopback == net.FlagLoopback {
		ip, err := ipport(c.Interface, addr, c.Port)
		if err != nil {
			return nil, e.Push(err, ErrCantFindInt)
		}
		dst, err = net.ResolveUDPAddr("udp", ip)
		if err != nil {
			return nil, e.Push(err, ErrCantFindInt)
		}
	} else if !c.NotMulticast && c.iface.Flags&net.FlagMulticast == net.FlagMulticast {
		dst, err = c.multicast(c.conn.LocalAddr())
		if err != nil {
			return nil, e.Push(err, ErrCantFindInt)
		}
	} else if c.iface.Flags&net.FlagBroadcast == net.FlagBroadcast {
		dst, err = broadcast(c.conn.LocalAddr(), c.Port)
		if err != nil {
			return nil, e.Push(err, ErrCantFindInt)
		}
	} else {
		return nil, e.Push(e.New("interface isn't suported: %v", c.iface.Flags), ErrCantFindInt)
	}
	log.ProtoLevel().Tag("discover", "client").Printf("Local ip %v.", c.conn.LocalAddr())
	log.ProtoLevel().Tag("discover", "client").Printf("Try to contact server in %v.", dst)
	now := time.Now()
	end := now.Add(c.Timeout)
	for d := now; d.Before(end) || d.Equal(end); d = time.Now() {
		req, err := c.Request(dst)
		if err != nil {
			return nil, e.Forward(err)
		}

		req.Id = c.Id
		req.Ip = c.conn.LocalAddr().String()

		err = c.encode(protoReq, req, dst)
		if e.Contains(err, "i/o timeout") {
			log.Errorf("Error %v -> %v: %v", c.conn.LocalAddr(), dst, err)
			continue
		} else if err != nil {
			return nil, e.Forward(err)
		}

		resp, err := c.response()
		if e.Contains(err, "i/o timeout") {
			log.Errorf("Error %v -> %v: %v", c.conn.LocalAddr(), dst, err)
			continue
		} else if err != nil {
			return nil, e.Forward(err)
		}

		c.Id = resp.Id

		err = c.encode(protoConfirm, resp.Id, dst)
		if e.Contains(err, "i/o timeout") {
			log.Errorf("Error %v -> %v: %v", c.conn.LocalAddr(), dst, err)
			continue
		} else if err != nil {
			return nil, e.Forward(err)
		}

		rp, err := c.response()
		if e.Contains(err, "i/o timeout") {
			log.Errorf("Error %v -> %v: %v", c.conn.LocalAddr(), dst, err)
			continue
		} else if err != nil {
			return nil, e.Forward(err)
		}

		if rp.Id != resp.Id {
			return nil, e.New("protocol fail wrong response")
		}

		go func(dst *net.UDPAddr) {
			for {
				select {
				case <-time.After(c.Keepalive):
					log.ProtoLevel().Tag("client", "discover").Printf("Send keep alive to %v", dst)
					err := c.keepalive(dst)
					if err != nil {
						log.Tag("client", "discover").Errorf("Keep alive to %v failed: %v", dst, err)
						return
					}
				case ch := <-c.stopKa:
					ch <- struct{}{}
					return
				}
			}
		}(dst)

		return resp, nil
	}
	return nil, e.New("can't find the server")
}
コード例 #23
0
ファイル: proto.go プロジェクト: fcavani/gormethods
func sortIncoming(reader *bufio.Reader, bufs *buffers, domain string) error {
	scanner := scan.NewScanner(reader, 1e9)
	split := func(buf []byte, atEOF bool) (advance int, token []byte, err error) {
		status := 0
		start := -1
		end := -1
		for i, b := range buf {
			switch {
			case status == 0:
				if b == 0xAA {
					start = i
					status++
					continue
				}
				status = 0
			case status >= 1 && status <= sepsize-2:
				if b == 0xAA {
					status++
					continue
				}
				status = 0
			case status == sepsize-1:
				if b == 0xAA {
					end = i
					status++
					break
				}
				status = 0
			}
		}

		if start == -1 || end == -1 {
			if atEOF {
				return 0, nil, io.EOF
			}
			return 0, nil, nil
		}
		end++
		if end > 1 && len(buf) == end {
			if atEOF {
				return 0, nil, io.EOF
			}
			return 0, nil, nil
		}

		_, size, err := parsePkg(buf[start:])
		if e.Equal(err, ErrMissData) {
			// Buffer is too small to parser, wait more data
			return 0, nil, nil
		} else if err != nil {
			if atEOF {
				return 0, nil, io.EOF
			}
			return 0, nil, nil
		}
		adv := start + offset3 + int(size)

		if adv > len(buf[start:]) {
			if atEOF {
				return 0, nil, io.EOF
			}
			return 0, nil, nil
		}

		return adv, buf[start:adv], nil
	}
	scanner.Split(split)

	for scanner.Scan() {
		buf := scanner.Bytes()
		stream, size, err := parsePkg(buf)
		if err != nil {
			log.ProtoLevel().Tag("gormethods", "proto", domain).Printf("Invalid stream: %v", err)
			bufs.ErrorAll(e.Forward(err))
			continue
		}
		log.ProtoLevel().Tag("gormethods", "proto", domain).Printf("Read (%v): %v", stream, pkg(buf))
		end := offset3 + int(size)
		if end != len(buf) {
			log.Tag("gormethods", "proto", domain).Error("Parser error!")
			return e.New("parser error")
		}
		b := buf[offset3:end]
		err = bufs.Write(uint32(stream), b)
		if err != nil {
			log.ProtoLevel().Tag("gormethods", "proto", domain).Printf("Can't store the data for stream %v: %v", stream, err)
			bufs.Error(uint32(stream), e.Forward(err))
			continue
		}
		log.ProtoLevel().Tag("gormethods", "proto", domain).Printf("Data write to buffer. Stream: %v", stream)
	}

	log.ProtoLevel().Tag("gormethods", "proto", domain).Printf("Scanner quit.")

	err := scanner.Err()
	if e.Contains(err, "use of closed network connection") || err == io.EOF || e.Contains(err, "i/o timeout") {
		return e.Push(err, ErrNetwork)
	} else if err != nil {
		log.Tag("gormethods", "proto", domain).Errorf("Error scaning the data. Err: %v", err)
		return e.Forward(err)
	}

	return nil
}
コード例 #24
0
ファイル: barrier.go プロジェクト: fcavani/gormethods
// NewBarrier creates a barrier that will be used to syncronize two events in
// diferent functions or diferent goroutine, It return a handler that must be
// closed.
func NewBarrier() *Barrier {
	b := &Barrier{
		fns:          make([]func() error, 0),
		chreq:        make(chan chan func() error),
		chclose:      make(chan chan struct{}),
		first:        make(chan func() error),
		last:         make(chan func() error),
		queue:        make([]chan func() error, 0),
		chShutdown:   make(chan struct{}),
		chIsShutdown: make(chan bool),
	}
	go func() {
		shutdown := false
		defer func() {
			log.ProtoLevel().Tag("gormethods", "barrier").Println("Barrier goroutine is gone.")
		}()
		log.ProtoLevel().Tag("gormethods", "barrier").Println("New barrier")
		for {
			select {
			case ch := <-b.chclose:
				log.ProtoLevel().Tag("gormethods", "barrier").Println("Barrier close 1")
				for _, chq := range b.queue {
					close(chq)
				}
				log.ProtoLevel().Tag("gormethods", "barrier").Println("Barrier close 2")
				ch <- struct{}{}
				log.ProtoLevel().Tag("gormethods", "barrier").Println("Barrier close 3")
				b.isclosed = true
				return
			case fn := <-b.first:
				if len(b.queue) > 0 {
					b.dequeue(fn)
					continue
				}
				b.fns = append([]func() error{fn}, b.fns...)
			case fn := <-b.last:
				if len(b.queue) > 0 {
					b.dequeue(fn)
					continue
				}
				b.fns = append(b.fns, fn)
			case ch := <-b.chreq:
				if len(b.fns) == 0 {
					b.queue = append(b.queue, ch)
					continue
				}
				ch <- b.fns[0]
				if len(b.fns) > 1 {
					b.fns = b.fns[1:]
				} else {
					if shutdown {
						log.ProtoLevel().Tag("gormethods", "barrier").Println("Barrier shutdown")
						for _, ch := range b.queue {
							close(ch)
						}
						b.isclosed = true
						return
					}
					b.fns = b.fns[:0]
				}
			case <-b.chShutdown:
				shutdown = true
				if len(b.fns) == 0 {
					log.ProtoLevel().Tag("gormethods", "barrier").Println("Barrier shutdown")
					for _, ch := range b.queue {
						close(ch)
					}
					b.isclosed = true
					return
				}
			case b.chIsShutdown <- shutdown:
			}
		}
	}()
	return b
}
コード例 #25
0
ファイル: proto-server.go プロジェクト: fcavani/gormethods
func (p *protoServer) protocol(conn SessionConn) {
	dec := msgpack.NewDecoder(conn)
	enc := msgpack.NewEncoder(conn)
	log.ProtoLevel().Tag("server", "gormethods").Printf("Waiting decode %v %v %v", conn.SessionName(), conn.RemoteAddr(), conn.StreamNum())
	var req ReqInst
	err := dec.Decode(&req)
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Fail to decode instance request from %v: %v", conn.RemoteAddr(), err)
		conn.Close()
		return
	}
	inst := req.Inst
	if req.Inst != "" && req.Obj == "" {
		err = p.namedInst(conn.SessionName(), req.Inst)
		if err != nil {
			log.Tag("server", "gormethods").Errorf("Error open %v instance from %v: %v", req.Inst, conn.RemoteAddr(), err)
			er := enc.Encode(&RespInst{
				Err: e.Forward(err),
			})
			if err != nil {
				log.Tag("server", "gormethods").Errorf("Fail to encode instance reponse to %v: %v", conn.RemoteAddr(), er)
			}
			conn.Close()
			return
		}
		log.ProtoLevel().Tag("server", "gormethods").Printf("Session %v initiated by %v %v", conn.SessionName(), conn.RemoteAddr(), conn.StreamNum())
	} else if req.Inst == "" && req.Obj != "" {
		inst, err = p.newInst(conn.SessionName(), conn.Auth(), req.Obj, req.Args...)
		if err != nil {
			log.Tag("server", "gormethods").Errorf("Error creating instance %v from %v: %v", req.Inst, conn.RemoteAddr(), err)
			er := enc.Encode(&RespInst{
				Err: e.Forward(err),
			})
			if err != nil {
				log.Tag("server", "gormethods").Errorf("Fail to encode instance reponse to %v: %v", conn.RemoteAddr(), er)
			}
			conn.Close()
			return
		}
		log.ProtoLevel().Tag("server", "gormethods").Printf("Object %v (%v) initiated by %v %v", req.Obj, inst, conn.RemoteAddr(), conn.StreamNum())
	} else {
		log.Tag("server", "gormethods").Errorf("Invalid request from %v.", conn.RemoteAddr())
		return
	}
	err = enc.Encode(&RespInst{
		Inst: inst,
		Err:  nil,
	})
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Fail to encode instance reponse to %v: %v", conn.RemoteAddr(), err)
		conn.Close()
		return
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Instance %v initiated.", inst)
	go func() {
		err := p.FnInst(&instConn{
			SessionConn: conn,
			inst:        inst,
			enc:         msgpack.NewEncoder(conn),
			dec:         msgpack.NewDecoder(conn),
		})
		if err != nil {
			conn.Close()
			log.ProtoLevel().Tag("server", "gormethods").Printf("Protocol close. %v %v", conn.RemoteAddr(), conn.StreamNum())
		}
	}()
}
コード例 #26
0
ファイル: client.go プロジェクト: fcavani/gormethods
func (c *client) Call(method string, args, retvals []reflect.Value) (err error) {
	start := time.Now()
	log.ProtoLevel().Tag("gormethods", "client", "call").Printf("Start call to %v %v %v", c.SessionName, c.InstanceName, method)
	defer func() {
		log.ProtoLevel().Tag("gormethods", "client", "call").Printf("Call to %v %v %v returned after %v with error: %v", c.SessionName, c.InstanceName, method, time.Since(start), err)
	}()

	conn, err := c.clones.Request(c.session, c.InstanceName)
	if err != nil {
		return e.Forward(err)
	}
	defer func() {
		if err != nil {
			log.ErrorLevel().Tag("client", "gormethods").Printf("Call to %v %v %v returned an error: %v", c.SessionName, c.InstanceName, method, err)
			conn.Close()
			return
		}
		er := c.clones.Return(c.SessionName, c.InstanceName, conn)
		if er != nil {
			log.DebugLevel().Tag("client", "gormethods").Println("Can't returns object:", e.Trace(e.Forward(er)))
		}
	}()

	conn.Mutex().Lock()
	defer conn.Mutex().Unlock()
	enc := conn.Encoder()
	dec := conn.Decoder()

	if c.ConnTimeout > 0 {
		err = conn.SetWriteDeadline(time.Now().Add(c.ConnTimeout))
		if err != nil {
			return e.Forward(err)
		}
	}
	err = enc.Encode(msgtypes.Call)
	if err != nil {
		return e.Forward(err)
	}
	if c.ConnTimeout > 0 {
		err = conn.SetWriteDeadline(time.Now().Add(c.ConnTimeout))
		if err != nil {
			return e.Forward(err)
		}
	}

	// Substituir os channels por uma representação destes
	chs := mkChClient(args)

	err = enc.Encode(&reqCall{
		Method: method,
		Args:   args,
	})
	if err != nil {
		return e.Forward(err)
	}

	if len(chs) > 0 {
		err = recvInstance(dec, chs)
		if err != nil {
			return e.Forward(err)
		}
		// conn
		err = c.setupConn(chs)
		if err != nil {
			return e.Forward(err)
		}
		// gorotine
		c.startGorotineCh(chs)
	}

	// Olhar os args e descobrir quem é channel
	// Cada channel tem que corresponder a uma nova instancia
	// uma nova conn tem que ser pedida com isso:
	// conn, err := c.clones.Request(c.session, c.InstanceName)

	// Procurar por channels nos argumentos
	// Fazer setup de um ? e deixar uma gorotine fazendo esperando lá até o canal fechar

	if c.ConnTimeout > 0 {
		err = conn.SetWriteDeadline(time.Time{})
		if err != nil {
			return e.Forward(err)
		}
		err = conn.SetReadDeadline(time.Now().Add(c.ConnTimeout))
		if err != nil {
			return e.Forward(err)
		}
	}

	resp := respCall{}
	err = dec.Decode(&resp)
	if err != nil {
		return e.Forward(err)
	}
	if c.ConnTimeout > 0 {
		err = conn.SetReadDeadline(time.Time{})
		if err != nil {
			return e.Forward(err)
		}
	}
	if resp.Err != nil {
		return e.Forward(resp.Err)
	}
	err = resp.Retvals(c, retvals)
	if err != nil {
		return e.Forward(err)
	}
	return
}
コード例 #27
0
ファイル: proto-server.go プロジェクト: fcavani/gormethods
func (s *servStreams) zero() {
	go func() {
		defer func() {
			s.termZero()
			log.ProtoLevel().Tag("gormethods", "server", "proto").Println("Stop zero.")
			// TODO: find a way to verify if zero is done before Close is end.
			// Now the leek test won't succed every time.
			//s.closedZero <- struct{}{}
		}()
		buf := make([]byte, payloadSize)
	F:
		for {
			n, err := s.bufs.Read(0, buf)
			if err != nil {
				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't read from stream 0: %v", err)
				break F
			}
			if n != payloadSize {
				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Not enougth data from stream 0")
				continue F
			}
			cmd, param, err := parseCmd(buf)
			if err != nil {
				continue F
			}
			switch cmd {
			case newStream:
				if s.streamCount >= 1<<32-1 {
					log.ProtoLevel().Tag("gormethods", "server", "proto").Print("Max num of open streams.")
					buf := newStreamResponse(fail, 0)
					for count := 0; count < len(buf[count:]); {
						n, err := s.write(0, buf)
						if e.Equal(err, ErrNetwork) {
							return
						} else if err != nil {
							log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't write new stream reponse for %v: %v", s.conn.RemoteAddr(), err)
							break
						}
						count += n
					}
					continue F
				}
				num := atomic.AddUint32(&s.streamCount, 1)
				err = s.streams.Activate(num)
				if err != nil {
					log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't activate stream %v.", num)
					buf := newStreamResponse(fail, 0)
					for count := 0; count < len(buf); {
						n, err := s.write(0, buf[count:])
						if e.Equal(err, ErrNetwork) {
							writeError(s, num, e.Forward(err))
							return
						} else if err != nil {
							writeError(s, num, e.Forward(err))
							break
						}
						count += n
					}
					continue F
				}
				err = s.bufs.New(num)
				if err != nil {
					log.ProtoLevel().Tag("gormethods", "server", "proto").Errorf("Error creating buffer for stream %v: %v", num, err)
					continue F
				}
				buf := newStreamResponse(streamOk, num)
				for count := 0; count < len(buf); {
					n, err := s.write(0, buf[count:])
					if e.Equal(err, ErrNetwork) {
						writeError(s, num, e.Forward(err))
						return
					} else if err != nil {
						writeError(s, num, e.Forward(err))
						continue F
					}
					count += n
				}

				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Request stream %v from %v", num, s.conn.RemoteAddr())
				s.acceptFifo <- &newAccept{
					stream: &servStream{
						num: num,
						s:   s,
					},
					err: nil,
				}
			case closeStream:
				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Close stream %v", param)
				err = s.streams.Deactivate(param)
				if err != nil && !e.Equal(err, ErrStreamNotFound) {
					log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't deactivate stream %v: %v", param, err)
					buf := newStreamResponse(fail, 1)
					for count := 0; count < len(buf); {
						n, err := s.write(0, buf[count:])
						if e.Equal(err, ErrNetwork) {
							writeError(s, param, e.Forward(err))
							return
						} else if err != nil {
							writeError(s, param, e.Forward(err))
							break
						}
						count += n
					}
					continue F
				}

				err = s.bufs.Delete(param)
				if err != nil && !e.Equal(err, ErrStreamNotFound) {
					log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Can't deactivate stream %v: %v", param, err)
					buf := newStreamResponse(fail, 2)
					for count := 0; count < len(buf); {
						n, err := s.write(0, buf[count:])
						if e.Equal(err, ErrNetwork) {
							writeError(s, param, e.Forward(err))
							return
						} else if err != nil {
							writeError(s, param, e.Forward(err))
							break
						}
						count += n
					}
					continue F
				}

				buf := newStreamResponse(ok, 0)
				for count := 0; count < len(buf); {
					n, err := s.write(0, buf[count:])
					if e.Equal(err, ErrNetwork) {
						writeError(s, param, e.Forward(err))
						return
					} else if err != nil {
						writeError(s, param, e.Forward(err))
						break
					}
					count += n
				}

				log.ProtoLevel().Tag("gormethods", "server", "proto").Printf("Close stream %v from %v", param, s.conn.RemoteAddr())
			}
		}
	}()
}
コード例 #28
0
ファイル: server.go プロジェクト: fcavani/discover
// Do method starts a goroutine that waites for the clients, and make responses with the
// Protocol function.
func (a *Server) Do() error {
	if a.Port == "" {
		a.Port = "0"
	}
	if a.BufSize <= 0 {
		a.BufSize = 1024
	}
	if a.Duration == 0 {
		a.Duration = 24 * time.Hour
	}
	if a.Name == "" {
		a.Name = "master"
	}
	a.seq = make([]*net.UDPAddr, 0)
	a.ctxs = newContexts(a.Duration, 300*time.Second)
	a.InitMCast()
	err := a.getInt()
	if err != nil {
		return e.Forward(err)
	}
	a.conn, err = a.bind()
	if err != nil {
		return e.Forward(err)
	}
	go func() {
		for {
			buf := make([]byte, a.BufSize)
			n, addr, err := a.conn.ReadFromUDP(buf)
			if e.Contains(err, "use of closed network connection") {
				return
			} else if err != nil {
				log.Tag("discover", "server").Printf("Server - ReadFromUDP (%v) failed: %v", addr, e.Trace(e.New(err)))
				continue
			}

			dec := gob.NewDecoder(bytes.NewReader(buf[:n]))
			var msg Msg
			err = dec.Decode(&msg)
			if err != nil {
				log.Tag("discover", "server").Printf("Can't decode data from %v.", addr)
				continue
			}

			pubkey, err := a.PubKeys.Get(msg.From)
			if err != nil {
				log.Tag("discover", "server").Printf("Invalid %v sender from %v.", msg.From, addr)
				continue
			}

			buf, err = msg.Message(pubkey, a.PrivateKey)
			if err != nil {
				log.Tag("discover", "server").Printf("Invalid message from %v: %v.", addr, err)
				continue
			}

			if len(buf) < binary.MaxVarintLen16 {
				log.Tag("discover", "server").Printf("Read insulficient data from %v.", addr)
				continue
			}
			typ, b := binary.Uvarint(buf[:binary.MaxVarintLen16])
			if b <= 0 {
				log.Tag("discover", "server").Print("Invalid package type from %v.", addr)
				continue
			}
			t := msgType(typ)
			log.ProtoLevel().Tag("server", "discover").Printf("Received %v request from %v.", t, addr)
			switch t {
			case protoConfirm:
				go a.confirm(addr, msg.From, pubkey, buf[binary.MaxVarintLen16:])
			case protoReq:
				go a.request(addr, msg.From, pubkey, buf[binary.MaxVarintLen16:])
			case protoKeepAlive:
				go a.keepalive(addr, msg.From, pubkey, buf[binary.MaxVarintLen16:])
			default:
				log.Tag("discover", "server").Errorf("Protocol error. (%v)", typ)
			}
		}
	}()
	return nil
}
コード例 #29
0
ファイル: proto-server.go プロジェクト: fcavani/gormethods
func (p *protoServer) accept(conn net.Conn) {
	defer func() {
		conn.Close()
		log.ProtoLevel().Tag("server", "gormethods", "proto").Println("Accept close.")
	}()
	var err error
	enc := msgpack.NewEncoder(conn)
	dec := msgpack.NewDecoder(conn)
	if p.ConnTimeout > 0 {
		err = conn.SetReadDeadline(time.Now().Add(p.ConnTimeout))
		if err != nil {
			log.Tag("server", "gormethods").Errorf("Read deadline for %v failed: %v", conn.RemoteAddr(), err)
			conn.Close()
			return
		}
	}
	var req ProtoAuth
	err = dec.Decode(&req)
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Decode auth request for %v failed: %v", conn.RemoteAddr(), err)
		return
	}
	err = conn.SetReadDeadline(time.Time{})
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Read deadline for %v failed: %v", conn.RemoteAddr(), err)
		return
	}
	// Check the protocol version
	if req.ProtoVersion != ProtoVersion {
		log.Tag("server", "gormethods").Errorf("Wrong protocol version. Requered version is %v, current version is %v.", ProtoVersion, req.ProtoVersion)
		er := enc.Encode(&ErrResp{
			Err: e.New("wrong protocol version"),
		})
		if er != nil {
			log.Tag("server", "gormethods").Errorf("Encode auth response for %v failed: %v", conn.RemoteAddr(), er)
			return
		}
		return
	}
	// Authenticate
	err = p.Insts.AuthSession(req.Sess, req.Auth)
	if err != nil {
		er := enc.Encode(&ErrResp{
			Err: e.Forward(err),
		})
		if er != nil {
			log.Tag("server", "gormethods").Errorf("Encode auth response for %v failed: %v", conn.RemoteAddr(), er)
			return
		}
		return
	}
	// If everthing is ok send nil
	err = enc.Encode(&ErrResp{
		Err: nil,
	})
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Encode auth response for %v failed: %v", conn.RemoteAddr(), err)
		return
	}
	income, err := newServStreams(conn, req.Sess, req.Auth, p)
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Start new streams for %v failed: %v", conn.RemoteAddr(), err)
		return
	}
	for {
		c, err := income.Accept()
		if e.Equal(err, ErrStreamClosed) {
			income.Close()
			return
		} else if err != nil {
			log.Tag("server", "gormethods").Errorf("Accept stream for %v failed: %v", conn.RemoteAddr(), err)
			income.Close()
			return
		}
		log.ProtoLevel().Tag("server", "gormethods").Printf("Accept new stream %v for %v.", c.StreamNum(), c.RemoteAddr())
		go p.protocol(c)
	}
}
コード例 #30
0
ファイル: barrier.go プロジェクト: fcavani/gormethods
// ReqShutdown waits until the read queue is empty and than shutdowns
// the Barrier control goroutine. The barrier will be useless after this.
func (b *Barrier) ReqShutdown() {
	log.ProtoLevel().Tag("gormethods", "barrier").Println("Request shutdown")
	b.chShutdown <- struct{}{}
}