示例#1
0
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)
		}
	}()
}
示例#2
0
文件: status.go 项目: fcavani/systemd
func (s *ServiceStatus) Init() error {
	var err error
	if s.Name == "" {
		return e.New(ErrInvServName)
	}
	s.conn, err = sd.NewSystemdConnection()
	if err != nil {
		return e.Forward(err)
	}
	err = s.conn.Subscribe()
	if err != nil {
		return e.Forward(err)
	}
	ch, cherr := s.conn.SubscribeUnits(s.Interval)
	go func() {
		for {
			select {
			case status := <-ch:
				if status == nil {
					continue
				}
				st, found := status[s.Name]
				if !found {
					log.Tag("systemd").Printf("Status of %v is unknow.", s.Name)
					s.setStatus(Unknow)
					continue
				}
				if s == nil {
					s.setStatus(Deleted)
					continue
				}
				if st.LoadState == "loaded" && st.ActiveState == "active" && st.SubState == "running" {
					s.setStatus(Running)
				} else if st.LoadState == "loaded" && st.ActiveState == "active" && st.SubState == "active" {
					s.setStatus(Running)
				} else if st.LoadState == "not-found" && st.ActiveState == "active" && st.SubState == "exited" {
					s.setStatus(Stopped)
				} else if st.LoadState == "loaded" && st.ActiveState == "inactive" && st.SubState == "dead" {
					s.setStatus(Stopped)
				} else {
					//ActiveState: deactivating, LoadState: loaded, SubState: stop-sigterm
					log.Tag("systemd").Printf("ActiveState: %v, LoadState: %v, SubState: %v", st.ActiveState, st.LoadState, st.SubState)
					s.setStatus(Other)
				}
			case err := <-cherr:
				log.Tag("systemd", "service", "status").Fatalln("SubscribeUnits error:", err)
			}
		}
	}()
	return nil
}
示例#3
0
func (s *Server) cleanUpChannelInstance(inst Valuer, conn InstConn) {
	if !inst.Instance().IsNil() {
		inst.Instance().Close()
		inst.NilInstance()
	}
	err := s.Insts.Delete(conn.SessionName(), conn.InstanceName())
	if err != nil && e.FindStr(err, "instance not found") == -1 {
		log.Tag("gormethods", "server", "channel").Errorf("Can't remove the instance %v/%v. %v", conn.SessionName(), conn.InstanceName(), err)
	}
}
示例#4
0
func (a *Server) sendErr(addr *net.UDPAddr, er error) {
	respBuf := bytes.NewBuffer([]byte{})
	enc := gob.NewEncoder(respBuf)
	msg := &Msg{
		Err: er,
	}
	err := enc.Encode(msg)
	if err != nil {
		log.Tag("discover", "server").Error("Error encoding erro response:", err)
		return
	}
	if respBuf.Len() > a.BufSize {
		log.Tag("discover", "server").Error("Error encoding erro response: error response is too long", respBuf.Len())
		return
	}
	_, _, err = a.conn.WriteMsgUDP(respBuf.Bytes(), nil, addr)
	if err != nil {
		log.Tag("discover", "server").Error("Error sending erro response:", err)
	}
}
示例#5
0
func (a *Server) keepalive(addr *net.UDPAddr, to string, tokey *rsa.PublicKey, buf []byte) {
	dec := gob.NewDecoder(bytes.NewReader(buf))
	var id string
	err := dec.Decode(&id)
	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 decoding id")))
		return
	}
	ctx, err := a.ctxs.Get(id)
	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("id is invalid")))
		return
	}
	a.sendResp(&Response{
		Id:  ctx.Id,
		Ip:  ctx.Addr.String(),
		Seq: ctx.Seq,
	}, to, tokey, addr)
}
示例#6
0
func (a *Server) request(addr *net.UDPAddr, to string, tokey *rsa.PublicKey, buf []byte) {
	dec := gob.NewDecoder(bytes.NewReader(buf))
	var req Request
	err := dec.Decode(&req)
	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 decoding request")))
		return
	}
	resp, err := a.Protocol(addr, &req)
	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("protocol error")))
		return
	}

	ctx, err := a.ctxs.Get(req.Id)
	if err != nil {
		resp.Id = req.Id
		resp.Ip = addr.String()
		a.lckSeq.Lock()
		resp.Seq = uint16(len(a.seq))
		a.lckSeq.Unlock()
		err = a.ctxs.Register(&context{
			Id:   req.Id,
			Seq:  resp.Seq,
			Addr: addr,
		})
		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("protocol error")))
			return
		}
	} else {
		resp.Id = ctx.Id
		resp.Ip = ctx.Addr.String()
		resp.Seq = ctx.Seq
	}
	a.sendResp(resp, to, tokey, addr)
}
示例#7
0
// 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
}
示例#8
0
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
	}
}
示例#9
0
func (p *protoServer) Start() error {
	var err error
	if p.FnInst == nil {
		log.Tag("server", "gormethods").Errorf("FnInst function is nil!")
		return e.New("failed to init server")
	}
	if p.TlsConfig != nil {
		p.listener, err = tls.Listen(p.Proto, p.Addr, p.TlsConfig)
	} else {
		p.listener, err = reuse.Listen(p.Proto, p.Addr)
	}
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Can't listen on interface %v proto %v: %v", p.Addr, p.Proto, e.Forward(err))
		return e.Forward(err)
	}
	err = p.chmodSocket(0660)
	if err != nil {
		log.Tag("server", "gormethods", "proto").Errorf("Fail to chmod socket %v: %v", p.listener.Addr(), e.Forward(err))
		return e.Forward(err)
	}
	p.closedListener = make(chan struct{})
	go func() {
		defer func() {
			log.Tag("server", "gormethods", "proto").Println("Listener accept close.")
			p.closedListener <- struct{}{}
		}()
		for {
			// Ok1
			conn, err := p.listener.Accept()
			if e.Contains(err, "use of closed network connection") {
				p.listener.Close()
				return
			} else if e.Contains(err, "too many open files") {
				p.listener.Close()
				log.Tag("server", "gormethods").Error(err)
				return
			} else if err != nil {
				p.listener.Close()
				log.Tag("server", "gormethods", "proto").Errorf("Accept for %v failed: %v", p.listener.Addr(), e.Forward(err))
				return
			}
			go p.accept(conn)
		}
	}()
	return nil
}
示例#10
0
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
}
示例#11
0
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")
}
示例#12
0
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
}
示例#13
0
func (s *Server) protoChannel(conn InstConn) error {
	chRetSend := make(chan struct{})
	chRetRecv := make(chan struct{})
	defer func() {
		select {
		case <-chRetSend:
			return
		case <-chRetRecv:
			return
		}
	}()
	inst, err := s.Insts.Get(conn.SessionName(), conn.InstanceName())
	if err != nil {
		log.Tag("gormethods", "server", "channel").Errorf("Error getting the instance %v/%v: %v", conn.SessionName(), conn.InstanceName(), e.Forward(err))
		return e.Forward(err)
	}

	if inst.Type() != WithChannel {
		log.Tag("gormethods", "server", "channel").Errorf("Instance %v/%v is of wrong type", conn.SessionName(), conn.InstanceName())
		return e.New("instance is of wrong type")
	}

	log.ProtoLevel().Tag("gormethods", "server", "channel").Printf("Start channel for %v/%v", conn.SessionName(), conn.InstanceName())

	switch inst.ChDir() {
	case reflect.RecvDir:
		go func(inst Valuer, conn InstConn) {
			defer func() {
				chRetRecv <- struct{}{}
			}()
			var err error
			dec := conn.Decoder()
			elem := reflect.New(inst.Instance().Type().Elem())
			for {
				var typ ChMsgType
				err = dec.Decode(&typ)
				if err != nil {
					s.cleanUpChannelInstance(inst, conn)
					break
				}
				switch typ {
				case ChMsgErr:
					er := &e.Error{}
					err = dec.Decode(er)
					if err != nil {
						s.cleanUpChannelInstance(inst, conn)
						break
					}
					if !e.Equal(er, ErrChClosed) {
						log.Tag("server", "gormethods").Errorln(er)
					}
					s.cleanUpChannelInstance(inst, conn)
					break
				case ChMsgValue:
					err = dec.DecodeValue(elem)
					if err != nil {
						s.cleanUpChannelInstance(inst, conn)
						break
					}
					inst.Instance().Send(elem.Elem())
				default:
					s.cleanUpChannelInstance(inst, conn)
					break
				}
			}
		}(inst, conn)
	case reflect.SendDir:
		go func(inst Valuer, conn InstConn) {
			defer func() {
				chRetSend <- struct{}{}
			}()
			var err error
			enc := conn.Encoder()
			for {
				val, ok := inst.Instance().Recv()
				if !ok {
					inst.NilInstance()
					err = enc.Encode(ChMsgErr)
					if err != nil {
						s.cleanUpChannelInstance(inst, conn)
						break
					}
					enc.Encode(e.New(ErrRecvChFail))
					s.cleanUpChannelInstance(inst, conn)
					break
				}
				err = enc.Encode(ChMsgValue)
				if err != nil {
					s.cleanUpChannelInstance(inst, conn)
					break
				}
				err = enc.EncodeValue(val)
				if err != nil {
					s.cleanUpChannelInstance(inst, conn)
					break
				}
			}
		}(inst, conn)
	default:
		log.Tag("gormethods", "server", "channel").Errorf("Instance %v/%v channel is of wrong direction", conn.SessionName(), conn.InstanceName())
		return e.New("wrong channel direction")
	}
	return nil
}
示例#14
0
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())
		}
	}()
}
示例#15
0
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)
	}
}
示例#16
0
// 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
}
示例#17
0
func (c *client) startGorotineCh(channels []*ChannelInstance) {
	for _, ci := range channels {
		go func(ci *ChannelInstance) {
			defer func() {
				r := recover()
				if r == nil {
					return
				}
				err, ok := r.(error)
				if !ok {
					panic(r)
				}
				if err.Error() == "close of closed channel" {
					return
				}
				panic(r)
			}()
			defer ci.Conn.Close()
			ci.Conn.Mutex().Lock()
			defer ci.Conn.Mutex().Unlock()
			enc := ci.Conn.Encoder()
			dec := ci.Conn.Decoder()
			if c.ConnTimeout > 0 {
				err := ci.Conn.SetWriteDeadline(time.Now().Add(c.ConnTimeout))
				if err != nil {
					log.Tag("client", "gormethods").Errorln("Fail to set write deadline:", e.Trace(e.Forward(err)))
					return
				}
			}
			err := enc.Encode(msgtypes.Channel)
			if err != nil {
				log.Tag("client", "gormethods").Errorln("Request channel instance failed:", e.Trace(e.Forward(err)))
				return
			}
			if c.ConnTimeout > 0 {
				err = ci.Conn.SetReadDeadline(time.Time{})
				if err != nil {
					log.Tag("client", "gormethods").Errorln("Fail to set write deadline:", e.Trace(e.Forward(err)))
					return
				}
			}
			elem := ci.MakeNewPtrElem()
			switch ci.Ch.Type().ChanDir() {
			case reflect.RecvDir:
				for {
					// Channel have a min buffer length of 1
					val, ok := ci.Ch.Recv()
					if !ok {
						err = enc.Encode(ChMsgErr)
						if err != nil {
							break
						}
						err = enc.Encode(e.New(ErrChClosed))
						break
					}
					err = enc.Encode(ChMsgValue)
					if err != nil {
						break
					}
					err = enc.EncodeValue(val)
					if err != nil {
						break
					}
				}
			case reflect.SendDir:
				for {
					var typ ChMsgType
					err = dec.Decode(&typ)
					if err != nil {
						// TODO: Como detectar se o canal foi fechado?
						ci.Ch.Close()
						break
					}
					switch typ {
					case ChMsgErr:
						er := &e.Error{}
						err = dec.Decode(er)
						if err != nil {
							ci.Ch.Close()
							break
						}
						if !e.Equal(er, ErrRecvChFail) {
							log.Tag("client", "gormethods").Errorln(er)
						}
						ci.Ch.Close()
						break
					case ChMsgValue:
						err = dec.Decode(elem.Interface())
						if err != nil {
							ci.Ch.Close()
							break
						}
						ci.Ch.Send(elem.Elem())
					default:
						break
					}
				}
			default:
				log.Tag("client", "gormethods").Errorln("Channel direction not supported")
				break
			}
		}(ci)
	}
}
示例#18
0
func (s *Server) protoCall(conn InstConn) (err error) {
	enc := conn.Encoder()
	dec := conn.Decoder()
	defer func() {
		if err != nil {
			err = enc.Encode(&respCall{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)
			}
		}
	}()

	inst, err := s.Insts.Get(conn.SessionName(), conn.InstanceName())
	if err != nil {
		log.Tag("server", "gormethods").Errorf("Error getting the instance %v/%v: %v", conn.SessionName(), conn.InstanceName(), e.Forward(err))
		err = e.Forward(err)
		return
	}

	if inst.Type() != WithValue {
		log.Tag("server", "gormethods").Errorf("Instance %v/%v is of wrong type", conn.SessionName(), conn.InstanceName())
		return e.New("instance is of wrong type")
	}

	log.ProtoLevel().Tag("gormethods", "server", "call").Printf("Call %v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()))

	var req reqCall
	err = dec.Decode(&req)
	if e.Find(err, io.EOF) >= 0 {
		return e.Push(err, ErrWire)
	} else if err != nil {
		log.ProtoLevel().Tag("server", "gormethods").Printf("Decode %v -> %v (%v) error: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), err)
		err = e.Push(err, ErrWire)
		return
	}

	// Tratar argumentos (req.Args) com channel

	// 	criar channel
	// 	recebe do channel envia pelo conn
	// 	recebe do conn envia para channel
	// 	(faz isso até fechar o channel em um dos lados)

	// substutui em req.Args os channels

	// Se existem channels enviar instancias

	err = s.mkChServer(conn, req.Args, enc)
	if err != nil {
		err = e.Forward(err)
		log.Tag("server", "gormethods").Errorf("Channel arguments setup failed: %v", err)
		return
	}

	method := inst.Instance().MethodByName(req.Method)
	if !method.IsValid() {
		err = e.Push(e.New(ErrMethodNotFound), e.New("method %v not found", req.Method))
		log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), conn.InstanceName(), err)
		return
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Call %v/%v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()), req.Method)
	var retvals []reflect.Value
	if method.Type().IsVariadic() {
		retvals = method.CallSlice(req.Args)
	} else {
		retvals = method.Call(req.Args)
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Call returned %v/%v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()), req.Method)
	for i := range retvals {
		var exp *Export
		exp, err = s.Insts.ExportGet(conn.SessionName(), conn.InstanceName(), req.Method, i)
		if err != nil {
			continue
		}
		var instname string
		instname, err = rand.Chars(16, rand.NumberLetters, "go")
		if err != nil {
			err = e.Push(err, "can't create the instance name for exported retval")
			log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), conn.InstanceName(), err)
			return
		}
		owners := auth.NewPlainTextCredentials()
		err = owners.Add(conn.Auth())
		if err != nil {
			err = e.Push(err, "can't authorize the exported retval")
			log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), conn.InstanceName(), err)
			return
		}
		err = s.Insts.New(conn.SessionName(), instname, retvals[i], owners)
		if err != nil {
			err = e.Push(err, "can't crete the instance for the exported retval")
			log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), instname, err)
			return
		}
		for _, to := range exp.ToExport {
			err = s.Insts.Export(conn.SessionName(), instname, to)
			if err != nil {
				err = e.Push(err, e.New("can't export %v/%v %v %v %v to %v", conn.SessionName(), instname, to.Method, to.RetvalPos, types.Name(retvals[i].Interface()), types.Name(exp.Client)))
				log.Tag("server", "gormethods").Errorf("Error in call %v/%v: %v", conn.SessionName(), conn.InstanceName(), err)
				return
			}
		}
		exp.Client.Associate(conn.SessionName(), instname, conn.Auth())
		retvals[i] = reflect.ValueOf(exp.Client)
		continue
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Send returned values %v/%v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()), req.Method)
	err = enc.Encode(&respCall{
		Vals: retvals,
		Err:  nil,
	})
	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)
		return
	}
	log.ProtoLevel().Tag("server", "gormethods").Printf("Send returned values done %v/%v %v %v", conn.SessionName(), conn.InstanceName(), types.NameOf(inst.Instance().Type()), req.Method)
	return
}