Beispiel #1
0
func (s *servStreams) write(stream uint32, b []byte) (int, error) {
	s.lckSend.Lock()
	defer s.lckSend.Unlock()
	buf := make([]byte, sepsize+binary.MaxVarintLen32*2)
	header(buf, stream, len(b))
	n, err := s.conn.Write(append(buf, b...))
	if e.Contains(err, "use of closed network connection") || e.Contains(err, "EOF") || e.Contains(err, "i/o timeout") {
		return n, e.Push(err, ErrNetwork)
	}
	return n, nil
}
Beispiel #2
0
func (vs *VirtualServer) forceRestart() error {
	vs.status.Log(status.Verbose, "Forcing kill server %v.", vs.VirtualServerName)
	pid, err := util.ReadPidInt(vs.PidFile)
	if e.Contains(err, ErrNoSuchFile) {
		vs.status.Log(status.Verbose, "Server %v is about to restart. Pid file not found.", vs.VirtualServerName)
		err := vs.forceKill()
		if err != nil {
			msg := "Forcekill script failed in " + vs.VirtualServerName + " with error: " + err.Error() + ". Giving up restart server."
			msg += " Trace: " + e.Trace(e.Forward(err))
			vs.status.Log(status.Verbose, msg)
			return nil
		}
		goto restart
	} else if err != nil {
		return e.Forward(err)
	}

	err = syscall.Kill(pid, 9)
	if err != nil {
		return e.Forward(err)
	}

restart:
	err = vs.beforeStart()
	if err != nil {
		return e.Forward(err)
	}

	err = vs.restart()
	if err != nil {
		return e.Forward(err)
	}
	return nil
}
Beispiel #3
0
func (d *Daemon) exec(cmd string, args ...string) error {
	done := make(chan error, 1)
	c := exec.Command(cmd, args...)
	c.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	err := c.Start()
	if err != nil {
		return e.Forward(err)
	}
	go func() {
		done <- c.Wait()
	}()
	select {
	case <-time.After(d.ExecTimeout):
		<-done // allow goroutine to exit
		err := c.Process.Kill()
		if err != nil {
			d.status.Log(status.Debug, "Failed to kill command %v for %v.", cmd, d.DaemonName)
			return e.Forward(err)
		}
		d.status.Log(status.Debug, "Command %v exec for %v was killed, timeout.", cmd, d.DaemonName)
	case err := <-done:
		if e.Contains(err, "exit status") {
			msg := "Command %v exec for %v exited with this error: %v"
			d.status.Log(status.Debug, msg, cmd, d.DaemonName, e.Trace(e.Forward(err)))
			return e.Forward(err)
		} else if err != nil {
			return e.Forward(err)
		}
	}
	return nil
}
Beispiel #4
0
func (vs *VirtualServer) exec(cmd string, args ...string) error {
	done := make(chan error, 1)
	c := exec.Command(cmd, args...)
	err := c.Start()
	if err != nil {
		return e.Forward(err)
	}
	go func() {
		done <- c.Wait()
	}()
	select {
	case <-time.After(vs.ExecTimeout):
		<-done // allow goroutine to exit
		err := c.Process.Kill()
		if err != nil {
			vs.status.Log(status.Verbose, "Failed to kill command %v for %v.", cmd, vs.VirtualServerName)
			return e.Forward(err)
		}
		vs.status.Log(status.Verbose, "Command %v exec for %v was killed, timeout.", cmd, vs.VirtualServerName)
		return e.New("execution timeout")
	case err := <-done:
		if e.Contains(err, "exit status") {
			msg := "Command %v exec for %v existed with this error: %v"
			vs.status.Log(status.Verbose, msg, cmd, vs.VirtualServerName, e.Trace(e.Forward(err)))
			return e.Forward(err)
		} else if err != nil {
			return e.Forward(err)
		}
	}
	return nil
}
Beispiel #5
0
// 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
}
Beispiel #6
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
}
Beispiel #7
0
func (s *stream) Write(b []byte) (n int, err error) {
	s.lckSend.Lock()
	defer s.lckSend.Unlock()

	buf := make([]byte, offset3+len(b))
	err = header(buf, s.num, len(b))
	if err != nil {
		return 0, e.Forward(err)
	}
	copy(buf[offset3:], b)

	err = s.connect()
	if err != nil {
		return 0, e.Forward(err)
	}

	if s.connTimeout > 0 {
		err = s.conn.SetWriteDeadline(time.Now().Add(s.connTimeout))
		if err != nil {
			return 0, e.Forward(err)
		}
	}

	n, err = s.conn.Write(buf)
	if err == io.EOF || e.Contains(err, "i/o timeout") || e.Contains(err, "closed") {
		s.lckSend.Unlock()
		s.invConn()
		s.lckSend.Lock()
		return 0, e.Forward(err)
	} else if err != nil {
		s.lckSend.Unlock()
		s.invConn()
		s.lckSend.Lock()
		return 0, e.Forward(err)
	}

	err = s.conn.SetWriteDeadline(time.Time{})
	if err != nil {
		return 0, e.Forward(err)
	}

	n = n - offset3
	return
}
Beispiel #8
0
// PingUDP try to send something to UDP port
// and receive some thing. If connections is refused
// the host is considered down. If some other error,
// besides timeout, the host is down. If timeoutr
// I can't determine if the host is there or not.
func PingUDP(url *url.URL) error {
	conn, err := net.DialTimeout("udp", url.Host, DialTimeout)
	if err != nil {
		return e.New(err)
	}
	defer conn.Close()
	err = conn.SetDeadline(time.Now().Add(Deadline))
	_, err = conn.Write([]byte("Hi!"))
	if err != nil {
		return e.New(err)
	}
	buf := make([]byte, 100)
	_, err = conn.Read(buf)
	if e.Contains(err, "connection refused") {
		return e.Push(err, ErrNotAnwsered)
	} else if err != nil && !e.Contains(err, "i/o timeout") {
		return e.New(err)
	}
	return nil
}
Beispiel #9
0
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
}
Beispiel #10
0
func (t *txMongoDb) Get(key string) (interface{}, error) {
	val := types.Make(t.tentry)
	inter := val.Interface()
	err := t.c.Find(bson.M{"key": key}).One(inter)
	if _, ok := err.(*mgo.QueryError); ok {
		return nil, e.New(ErrKeyNotFound)
	} else if e.Contains(err, "not found") {
		return nil, e.New(ErrKeyNotFound)
	} else if err != nil {
		return nil, e.New(err)
	}
	return inter, nil
}
Beispiel #11
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
	}
}
Beispiel #12
0
func (vs *VirtualServer) beforeStart() error {
	vs.status.Log(status.Verbose, "Starting command %v.", vs.BeforeStartCmd)
	c := exec.Command(vs.BeforeStartCmd, vs.BeforeStartArgs...)
	buf, err := c.CombinedOutput()
	if e.Contains(err, "exit status") {
		msg := "Command " + vs.BeforeStartCmd + " exec for " + vs.VirtualServerName + " existed with this error: " + err.Error()
		msg += "\nBefore start output is:\n\n"
		msg += string(buf)
		vs.status.Log(status.Verbose, "Command "+vs.BeforeStartCmd+" exec failed.", msg)
		return e.Forward(err)
	} else if err != nil {
		return e.Forward(err)
	}
	vs.status.Log(status.Verbose, "Command %v done.", vs.BeforeStartCmd)
	return nil
}
Beispiel #13
0
func (t *txBoltDb) Put(key string, data interface{}) error {
	buf, err := t.enc.Encode(data)
	if err != nil {
		return e.Forward(err)
	}
	defer func() {
		t.bufs = append(t.bufs, buf)
	}()
	err = t.b.Put([]byte(key), buf)
	if e.Contains(err, "tx not writable") {
		return e.New(ErrReadOnly)
	} else if err != nil {
		return e.New(err)
	}
	return nil
}
Beispiel #14
0
func (d *Daemon) restartProcess() error {
	d.status.Log(status.Verbose, "Process %v is about to restart.", d.DaemonName)
	err := d.exec(d.RestartCmd, d.RestartArgs...)
	if e.Contains(err, "exit status") {
		d.status.Log(status.Verbose, "Restart command %v failed for %v with error: %v.", d.RestartCmd, d.DaemonName, e.Trace(e.Forward(err)))
		if d.ForceKillCmd != "" {
			err := d.forceKill()
			if err != nil {
				return e.Push(err, ErrGiveUpRestart)
			}
		} else {
			err := d.kill(syscall.SIGTERM)
			if e.Equal(err, ErrNoPid) {
				d.status.Log(status.Verbose, "Starting force kill for %v.", d.DaemonName)
				err := d.forceKill()
				if err != nil {
					return e.Push(err, ErrGiveUpRestart)
				}
			} else if err != nil {
				err := d.kill(syscall.SIGKILL)
				if err != nil {
					d.status.Log(status.Verbose, "Starting force kill for %v.", d.DaemonName)
					err := d.forceKill()
					if err != nil {
						return e.Push(err, ErrGiveUpRestart)
					}
				}
			}
		}
		d.status.Log(status.Verbose, "Process %v is about to restart.", d.DaemonName)
		err = d.exec(d.RestartCmd, d.RestartArgs...)
		if err != nil {
			err := d.forceKill()
			if err != nil {
				return e.Push(err, ErrGiveUpRestart)
			}
			d.status.Log(status.Verbose, "Process %v is about to restart, for the last time.", d.DaemonName)
			err = d.exec(d.RestartCmd, d.RestartArgs...)
			if err != nil {
				return e.Push(err, ErrGiveUpRestart)
			}
		}
	} else if err != nil {
		return e.Forward(err)
	}
	return nil
}
Beispiel #15
0
// InfoDB reports the status of the database.
// url is the url for the database and dbname is the name of the new database.
func InfoDB(url *url.URL, dbname string) (*DatabaseInfo, error) {
	c := &client{url}
	code, data, err := c.get(dbname, "", nil)
	if e.Contains(err, Err404) {
		return nil, e.Push(err, ErrDbNotFound)
	} else if err != nil {
		return nil, e.Push(err, "can't get database information")
	}
	if code != http.StatusOK {
		return nil, e.New("can't get database information, wrong response code: %v", code)
	}
	di := new(DatabaseInfo)
	err = json.Unmarshal(data, di)
	if err != nil {
		return nil, e.Push(err, "can't get database information")
	}
	return di, nil
}
Beispiel #16
0
func (d *Daemon) ping() error {
	for _, u := range d.Urls {
		if u == nil {
			return e.New(ErrUrlIsEmpty)
		}
		resolved, err := dns.ResolveUrl(u)
		if e.Contains(err, "invalid domain name") {
			resolved = u
		} else if err != nil {
			return e.Forward(err)
		}
		err = ping.Ping(resolved)
		if err != nil {
			d.status.LogAndEmail(status.Verbose, "", "Monitor ping failed for %v with error: %v", d.DaemonName, e.Trace(e.Forward(err)))
			return e.Push(err, ErrPingFailed)
		}
	}
	return nil
}
Beispiel #17
0
func TestLevels(t *testing.T) {
	buf := bytes.NewBuffer([]byte{})
	l := golog.New(buf, "", golog.LstdFlags)
	multi := NewMulti(NewSendToLogger(nil), DefFormatter, NewSendToLogger(l), DefFormatter)
	Log = New(multi, false).Domain("test")

	Log.SetLevel("all", DebugPrio)

	Println("oi")
	test(t, buf, "oi")

	ProtoLevel().Println("blá")
	err := testerr(buf, "blá")
	if err != nil && !e.Contains(err, "log didn't log") {
		t.Fatal(e.Trace(e.Forward(err)))
	} else if err == nil {
		t.Fatal("nil error")
	}

}
Beispiel #18
0
// DeleteDB removes the database. url is the url for the database and dbname is the name of
// the new database.
func DeleteDB(url *url.URL, dbname string) error {
	c := &client{url}
	code, resp, err := c.delete(dbname, "", nil)
	if e.Contains(err, Err404) {
		return e.Push(err, ErrDbNotFound)
	} else if err != nil {
		return e.Push(err, "can't delete the database")
	}
	if code != http.StatusOK {
		return e.New("can't delete the database, wrong response code: %v", code)
	}
	ok := new(Ok)
	err = json.Unmarshal(resp, ok)
	if err != nil {
		return e.Push(err, e.New("can't unserialize the response: %v", string(resp)))
	}
	if !ok.Ok {
		return e.New("can't delete the database: wrong response")
	}
	return nil
}
Beispiel #19
0
func TestPtr(t *testing.T) {
	host, err := LookupIp("200.149.119.183")
	if err != nil {
		t.Fatal(err)
	}
	if host != "183.119.149.200.in-addr.arpa.telemar.net.br" {
		t.Fatal("wrong host")
	}
	host, err = LookupIp("2800:3f0:4004:800::1013")
	if err != nil && !e.Contains(err, "can't resolve") {
		t.Fatal(err)
	}

	host, err = LookupIp("127.0.0.1")
	if err != nil {
		t.Fatal(err)
	}
	if host != "localhost" {
		t.Fatal("wrong host")
	}
}
Beispiel #20
0
func (c *cursorBoltDb) Del() (err error) {
	defer func() {
		if r := recover(); r != nil {
			er, ok := r.(error)
			if !ok {
				return
			}
			if e.Contains(er, "runtime error: index out of range") {
				err = e.New(ErrKeyNotFound)
				return
			}
		}
	}()
	if !c.b.Writable() {
		return e.New(ErrReadOnly)
	}
	err = c.c.Delete()
	if err != nil {
		return e.New(err)
	}
	return
}
Beispiel #21
0
func Put(tx *bolt.Tx, bucket []byte, keys [][]byte, data []byte) error {
	var err error
	var buf []byte
	var b *bolt.Bucket
	b, err = tx.CreateBucketIfNotExists(bucket)
	if err != nil {
		return e.Forward(err)
	}
	if len(keys) == 0 {
		return e.New("no keys")
	}
	if len(keys) >= 2 {
		for i := 0; i < len(keys)-1; i++ {
			buf = b.Get(keys[i])
			if buf == nil {
				id, err := rand.Uuid()
				if err != nil {
					return e.Forward(err)
				}
				buf = []byte(id)
				err = b.Put(keys[i], buf)
				if err != nil {
					return e.Forward(err)
				}
			}
			b, err = tx.CreateBucket(buf)
			if e.Contains(err, "bucket already exists") {
				b = tx.Bucket(buf)
			} else if err != nil {
				return e.Forward(err)
			}
		}
	}
	err = b.Put(keys[len(keys)-1], data)
	if err != nil {
		return e.Forward(err)
	}
	return nil
}
Beispiel #22
0
func NewCacheDisk(filename string, perm os.FileMode, opt *bolt.Options, images int) (*CacheDisk, error) {
	var err error
	cd := &CacheDisk{
		images: images,
	}
	cd.db, err = bolt.Open(filename, perm, opt)
	if err != nil {
		return nil, e.Forward(err)
	}
	err = cd.db.Update(func(tx *bolt.Tx) error {
		for _, b := range buckets {
			_, err := tx.CreateBucket([]byte(b))
			if err != nil && !e.Contains(err, "bucket already exists") {
				return e.New(err)
			}
		}
		return nil
	})
	if err != nil {
		return nil, e.Forward(err)
	}
	return cd, nil
}
Beispiel #23
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
}
Beispiel #24
0
func (t *txMongoDb) Put(key string, data interface{}) error {
	if !t.writeble {
		return e.New(ErrReadOnly)
	}
	n, err := t.c.Find(bson.M{"key": key}).Count()
	if err != nil {
		return e.New(err)
	}
	if n >= 1 {
		err := t.c.Update(bson.M{"key": key}, data)
		if e.Contains(err, "not found") {
			return e.New(ErrKeyNotFound)
		} else if err != nil {
			return e.New(err)
		}
		return nil
	}
	err = t.c.Insert(data)
	if err != nil {
		return e.New(err)
	}
	return nil
}
Beispiel #25
0
func TestFilter(t *testing.T) {
	Log = New(
		Filter(
			NewWriter(buf),
			Not(Op(Cnts, "msg", "not log")),
		).F(DefFormatter),
		false,
	).Domain("test")

	Println("log")
	test(t, buf, "log")

	Println("not log")
	err := testerr(buf, "not log")
	if err != nil && !e.Contains(err, "EOF") {
		t.Fatal(e.Trace(e.Forward(err)))
	} else if err == nil {
		t.Fatal("nil")
	}

	Println("log2")
	test(t, buf, "log2")

}
Beispiel #26
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
}
Beispiel #27
0
func Init(d *Daemon) (monitors.Monitor, error) {
	pid, err := util.ReadPidInt(d.PidFile)
	if err != nil && !e.Contains(err, "no such file or directory") {
		return nil, e.Forward(err)
	}

	if d.DaemonName == "" {
		return nil, e.New("empty daemon name")
	}
	if d.RestartCmd == "" {
		return nil, e.New("empty restart command")
	}
	if d.RestartArgs == nil {
		return nil, e.New("restart arguments is invalid")
	}
	if d.PidFile == "" {
		return nil, e.New("empty pid file")
	}
	if d.Sleep <= 0 {
		return nil, e.New("sleep is equal or less than zero")
	}
	if d.Tries < 0 {
		return nil, e.New("tries is equal or less than zero")
	}
	if d.Prio < 0 {
		return nil, e.New("prio have to be greater or equal to zero")
	}
	if d.Queue == nil {
		return nil, e.New("invalid queue")
	}
	if d.ExecTimeout <= 0 {
		return nil, e.New("exectution timeout is greater than zero")
	}

	d.MonitorBase = base.New()
	d.pid = pid
	d.killMonitor = make(chan bool)
	d.running = true
	d.status = status.NewStatuses(d.DaemonName, d.Email, definitions.LengthStatusHistory, status.NewStatus, d.SendEvent, nil)

	d.fswatcher, err = fsnotify.NewWatcher()
	if err != nil {
		return nil, e.Forward(err)
	}
	go func() {
	F:
		for {
			select {
			case ev := <-d.fswatcher.Event:
				if ev == nil {
					//watcher closed
					return
				}
				if ev.Name != d.PidFile {
					continue F
				}
				if ev.IsDelete() {
					d.pid = -1
				} else if !(ev.IsCreate() && ev.IsModify()) {
					continue F
				}
				d.changePid()
			case err := <-d.fswatcher.Error:
				if err != nil {
					d.status.Log(status.Verbose, "Pid file %v watcher error: %v", d.PidFile, e.Trace(e.Forward(err)))
				}
			}
		}
	}()

	err = d.fswatcher.Watch(filepath.Dir(d.PidFile))
	if err != nil {
		return nil, e.Push(err, e.New("invalid pid file %v", d.PidFile))
	}

	d.monitor()
	return d, nil
}
Beispiel #28
0
func (a *Alive) Connect() error {

	if a.events == nil {
		a.events = make(chan event.Event)
	}
	a.closePing = make(chan bool)

	resolved, err := dns.ResolveUrl(a.Url)
	if e.Contains(err, "invalid domain name") {
		resolved = a.Url
	} else if err != nil {
		a.setConnected(false)
		return e.Forward(err)
	}

	for i := 0; i < a.Tries; i++ {
		a.conn, err = net.Dial(resolved.Scheme, resolved.Host)
		if e.Contains(err, definitions.NetErrorConnectionRefused) ||
			e.Contains(err, definitions.NetErrorTimeOut) ||
			e.Contains(err, definitions.ErrCheckIsAliveNoRoute) ||
			e.Contains(err, definitions.ErrCheckIsAliveNoAnswerFromResolver) {
			time.Sleep(a.Wait)
			continue
		} else if err != nil {
			a.setConnected(false)
			return e.Forward(err)
		}
		break
	}
	if a.conn == nil {
		a.setConnected(false)
		if err != nil {
			return e.Push(e.New(err), definitions.ErrCheckIsAliveCantConnect)
		}
		return e.New(definitions.ErrCheckIsAliveCantConnect)
	}

	a.setConnected(true)

	dec := gob.NewDecoder(a.conn)
	enc := gob.NewEncoder(a.conn)

	go func() {
		defer func() {
			if a.conn != nil {
				a.conn.Close()
			}
			a.setConnected(false)
		}()
		for {
			select {
			case <-time.After(a.Wait):
				err := a.conn.SetWriteDeadline(time.Now().Add(5 * time.Second))
				if err != nil {
					return
				}
				err = enc.Encode("ping")
				if err != nil {
					a.Statuses.Log(status.Verbose, "Alive: Ping encode error: %v", err)
					return
				}
			case <-a.closePing:
				return
			}
		}
	}()

	go func() {
		defer func() {
			if a.conn != nil {
				a.conn.Close()
			}
			a.setConnected(false)
		}()
		for {
			var typ string
			err := dec.Decode(&typ)
			if err != nil {
				a.Statuses.Log(status.Verbose, "Alive: Decode error: %v", err)
				return
			}
			t, err := types.GetType(typ)
			if err != nil {
				a.Statuses.Log(status.Verbose, "Alive: GetType error: %v", err)
				return
			}
			ptr := types.Make(reflect.PtrTo(t))
			err = dec.DecodeValue(ptr)
			if err != nil {
				a.Statuses.Log(status.Verbose, "Alive: DecodeValue error: %v", err)
				return
			}
			val := reflect.Indirect(ptr)
			if val.IsValid() {
				a.events <- val.Interface().(event.Event)
			}
		}
	}()

	return nil
}
Beispiel #29
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
}
Beispiel #30
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")
}