예제 #1
0
// Save to DB
func (this *UdpSessionList) SaveSession(sid *uuid.UUID, s *UdpSession) error {
	v, ok := gUdpSessions.udpmap[s.Addr.String()]
	if ok {
		v.Reset(40 * time.Second)
	}
	return SetDeviceSession(sid.String(), gUdpTimeout, s.String(), s.DeviceId, s.Addr)
}
예제 #2
0
/*
NewJob creates a new job from the config as well as a job spec.  After creating
the job, calling job.Process() will actually perform the work.
*/
func NewJob(cfg *Config, spec *Spec, req *http.Request) *Job {
	var idUUID *gouuid.UUID
	var err error
	idUUID, err = gouuid.NewV4()
	if TestMode {
		idUUID, err = gouuid.NewV5(gouuid.NamespaceURL, []byte("0"))
	}

	if err != nil {
		cfg.Logger.WithField("error", err).Error("error creating uuid")
	}
	id := idUUID.String()

	bobfile := spec.Bobfile
	if bobfile == "" {
		bobfile = defaultBobfile
	}

	ret := &Job{
		Bobfile:        bobfile,
		ID:             id,
		Account:        spec.RepoOwner,
		GitHubAPIToken: spec.GitHubAPIToken,
		Ref:            spec.GitRef,
		Repo:           spec.RepoName,
		Workdir:        cfg.Workdir,
		InfoRoute:      "/jobs/" + id,
		LogRoute:       "/jobs/" + id + "/tail?n=" + defaultTail,
		logDir:         cfg.Workdir + "/" + id,
		Status:         "created",
		Created:        time.Now(),
	}
	ret.addHostToRoutes(req)

	out, file, err := newMultiWriter(ret.logDir)
	if err != nil {
		cfg.Logger.WithField("error", err).Error("error creating log dir")
		id = ""
	}

	ret.logFile = file
	ret.Logger = &logrus.Logger{
		Formatter: cfg.Logger.Formatter,
		Level:     cfg.Logger.Level,
		Out:       out,
	}

	if ret.GitHubAPIToken == "" {
		ret.GitHubAPIToken = cfg.GitHubAPIToken
	}

	if id != "" {
		jobs[id] = ret
	}

	return ret
}
예제 #3
0
// Get existed session from DB
func (this *UdpSessionList) GetSession(sid *uuid.UUID) (*UdpSession, error) {
	data, err := GetDeviceSession(sid.String())
	if err != nil {
		return nil, err
	}
	s := &UdpSession{
		Addr: &net.UDPAddr{},
	}
	err = s.FromString(data)
	if err != nil {
		return nil, err
	}
	s.Sid = sid.String()
	return s, nil
}
예제 #4
0
func (sr *SessionDbRow) InsertSession() (csi *ClearSessionId, err error) {

	var u4 *uuid.UUID

	u4, err = uuid.NewV4()
	if err != nil {
		return nil, err
	}

	csi = new(ClearSessionId)

	saltBytes := makeSalt()
	csi.Salt = hex.EncodeToString(saltBytes)
	csi.SessionToken = u4.String()

	sessionIdCrypt, err := csi.EncryptToken()
	if err != nil {
		err = fmt.Errorf("Failed to encrypt SessionToken: %s", err)
		return nil, err
	}

	insertSql := fmt.Sprintf(`
    INSERT INTO session.session (
        SessionId,
        SysUserId,
        start_dt,
        expires_dt,
        IpAddr,
        UserAgent)
     VALUES ($1, $2, now(), now() + interval '%d second', $3, $4)`, Conf.SessionTimeout)

	_, err = Conf.DatabaseHandle.Exec(insertSql, sessionIdCrypt, sr.SysUserId,
		sr.IpAddr, sr.UserAgent)

	if err != nil {
		glog.Errorf("Insert of session row failed: %s", err)
		return nil, err
	}

	return csi, nil
}
		It("should use an empty request ID if generating a new one fails", func() {
			instrumented_handler.GenerateUuid = func() (u *uuid.UUID, err error) {
				return nil, errors.New("test error")
			}
			h.ServeHTTP(httptest.NewRecorder(), req)
			Expect(req.Header.Get("X-CF-RequestID")).To(Equal("00000000-0000-0000-0000-000000000000"))
		})
	})

	Describe("event emission", func() {
		var requestId *uuid.UUID

		BeforeEach(func() {
			requestId, _ = uuid.NewV4()
			req.Header.Set("X-CF-RequestID", requestId.String())
		})

		Context("without an application ID or instanceIndex", func() {
			BeforeEach(func() {
				h.ServeHTTP(httptest.NewRecorder(), req)
			})

			It("should emit a start event with the right origin", func() {
				Expect(fakeEmitter.GetMessages()[0].Event).To(BeAssignableToTypeOf(new(events.HttpStart)))
				Expect(fakeEmitter.GetMessages()[0].Origin).To(Equal("testHandler/41"))
			})

			It("should emit a stop event", func() {
				Expect(fakeEmitter.GetMessages()[1].Event).To(BeAssignableToTypeOf(new(events.HttpStop)))
				stopEvent := fakeEmitter.GetMessages()[1].Event.(*events.HttpStop)
					UserAgent:     proto.String("our-testing-client"),
				}

				startEvent := factories.NewHttpStart(req, events.PeerType_Server, requestId)

				Expect(startEvent.GetTimestamp()).ToNot(BeZero())
				startEvent.Timestamp = nil

				Expect(startEvent).To(Equal(expectedStartEvent))
			})
		})

		Context("with an application ID", func() {
			It("should include it in the start event", func() {
				applicationId, _ := uuid.NewV4()
				req.Header.Set("X-CF-ApplicationID", applicationId.String())

				startEvent := factories.NewHttpStart(req, events.PeerType_Server, requestId)

				Expect(startEvent.GetApplicationId()).To(Equal(factories.NewUUID(applicationId)))
			})
		})

		Context("with an application instance index", func() {
			It("should include it in the start event", func() {
				req.Header.Set("X-CF-InstanceIndex", "1")

				startEvent := factories.NewHttpStart(req, events.PeerType_Server, requestId)

				Expect(startEvent.GetInstanceIndex()).To(BeNumerically("==", 1))
			})
		})
	})

	Context("event emission", func() {
		It("should emit a start event", func() {
			rt.RoundTrip(req)
			Expect(fakeEmitter.Messages[0].Event).To(BeAssignableToTypeOf(new(events.HttpStart)))
			Expect(fakeEmitter.Messages[0].Origin).To(Equal("testRoundtripper/42"))
		})

		Context("if request ID already exists", func() {
			var existingRequestId *uuid.UUID

			BeforeEach(func() {
				existingRequestId, _ = uuid.NewV4()
				req.Header.Set("X-CF-RequestID", existingRequestId.String())
			})

			It("should emit the existing request ID as the parent request ID", func() {
				rt.RoundTrip(req)
				startEvent := fakeEmitter.Messages[0].Event.(*events.HttpStart)
				Expect(startEvent.GetParentRequestId()).To(Equal(factories.NewUUID(existingRequestId)))
			})
		})

		Context("if round tripper returns an error", func() {
			It("should emit a stop event with blank response fields", func() {
				fakeRoundTripper.FakeError = errors.New("fakeEmitter error")
				rt.RoundTrip(req)

				Expect(fakeEmitter.Messages[1].Event).To(BeAssignableToTypeOf(new(events.HttpStop)))
예제 #8
0
					UserAgent:     proto.String("our-testing-client"),
				}

				startEvent := factories.NewHttpStart(req, events.PeerType_Server, requestId)

				Expect(startEvent.GetTimestamp()).ToNot(BeZero())
				startEvent.Timestamp = nil

				Expect(startEvent).To(Equal(expectedStartEvent))
			})
		})

		Context("with an application ID", func() {
			It("should include it in the start event", func() {
				applicationId, _ := uuid.NewV4()
				req.Header.Set("X-CF-ApplicationID", applicationId.String())

				startEvent := factories.NewHttpStart(req, events.PeerType_Server, requestId)

				Expect(startEvent.GetApplicationId()).To(Equal(factories.NewUUID(applicationId)))
			})
		})

		Context("with an application instance index", func() {
			It("should include it in the start event", func() {
				req.Header.Set("X-CF-InstanceIndex", "1")

				startEvent := factories.NewHttpStart(req, events.PeerType_Server, requestId)

				Expect(startEvent.GetInstanceIndex()).To(BeNumerically("==", 1))
			})
예제 #9
0
func (h *Handler) handle(t *UdpMsg) error {
	// TODO need decryption later

	mlen := len(t.Msg)
	if mlen < FrameHeaderLen {
		return fmt.Errorf("[protocol] invalid message length for device proxy,reason: mlen < FrameHeaderLen | %v < %v.", mlen, FrameHeaderLen)
	}
	// check opcode
	op := (0x7 & t.Msg[0])
	if op != 0x2 && op != 0x3 {
		return fmt.Errorf("[protocol] reason: wrong opcode, op!=2&&op!=3, op=", op)
	}

	if op == 0x2 {
		if mlen < FrameHeaderLen+DataHeaderLen {
			return fmt.Errorf("[protocol] invalid message length for protocol,  mlen < FrameHeaderLen+DataHeaderLen ,%v < %v", mlen, FrameHeaderLen+DataHeaderLen)
		}
		packNum := binary.LittleEndian.Uint16(t.Msg[2:4])
		bodyLen := int(binary.LittleEndian.Uint16(t.Msg[FrameHeaderLen+6:]))
		// discard msg if found checking error
		if t.Msg[FrameHeaderLen+8] != msgs.ChecksumHeader(t.Msg, FrameHeaderLen+8) {
			return fmt.Errorf("checksum header error %v!=%v", t.Msg[FrameHeaderLen+8], msgs.ChecksumHeader(t.Msg, FrameHeaderLen+8))
		}

		// check body
		if t.Msg[FrameHeaderLen+9] != msgs.ChecksumHeader(t.Msg[FrameHeaderLen+10:], 2+bodyLen) {
			return fmt.Errorf("checksum body error %v!=%v", t.Msg[FrameHeaderLen+9], msgs.ChecksumHeader(t.Msg[FrameHeaderLen+10:], 2+bodyLen))
		}

		var (
			sess      *UdpSession
			sid       *uuid.UUID
			err       error
			locker    Locker
			body      []byte
			bodyIndex int
		)

		bodyIndex = FrameHeaderLen + DataHeaderLen
		if bodyLen != len(t.Msg[bodyIndex:]) {
			return fmt.Errorf("wrong body length in data header: %d != %d", bodyLen, len(t.Msg[bodyIndex:]))
		}
		body = t.Msg[bodyIndex : bodyIndex+bodyLen]

		// parse data(udp)
		// 28 = FrameHeaderLen + 4
		c := binary.LittleEndian.Uint16(t.Msg[28:30])
		if c == CmdSyncState {
			glog.Infoln("执行设备状态同步")
			GMsgBusManager.Push2Bus(0, nil, t.Msg)
			return nil
		} else if c == 0x31 {
			glog.Infoln("执行报警信息同步")
			GMsgBusManager.Push2Bus(0, nil, t.Msg)
			return nil
			//TODO alarm msg synchronization
		} else if c != CmdGetToken {
			sid, err = uuid.Parse(t.Msg[bodyIndex : bodyIndex+16])
			if err != nil {
				return fmt.Errorf("parse session id error: %v", err)
			}

			locker = NewDeviceSessionLocker(sid.String())
			err = locker.Lock()
			if err != nil {
				return fmt.Errorf("lock session id [%s] failed: %v", sid, err)
			}
			sess, err = gUdpSessions.GetSession(sid)
			if err != nil {
				locker.Unlock()
				return fmt.Errorf("cmd: %X, sid: [%v], error: %v", c, sid, err)
			}
			err = sess.VerifySession(packNum)
			if err != nil {
				locker.Unlock()
				return fmt.Errorf("cmd: %X, verify session error: %v", c, err)
			}
		}

		output := make([]byte, bodyIndex)
		// copy same packNum into this ACK response
		copy(output[:bodyIndex], t.Msg[:bodyIndex])

		var res []byte
		switch c {
		case CmdGetToken:
			t.CmdType = c
			res, err = h.onGetToken(t, body)

		case CmdRegister:
			t.CmdType = c
			t.Url = h.kApiUrls[c]
			res, err = h.onRegister(t, sess, body)

		case CmdLogin:
			t.CmdType = c
			t.Url = h.kApiUrls[c]
			res, err = h.onLogin(t, sess, body)

		case CmdRename:
			t.CmdType = c
			t.Url = h.kApiUrls[c]
			res, err = h.onRename(t, sess, body)

		//case CmdDoBind:
		//	t.CmdType = c
		//	t.Url = h.kApiUrls[c]
		//	res, err = h.onDoBind(t, sess, body)

		case CmdHeartBeat:
			t.CmdType = c
			res, err = h.onHearBeat(t, sess, body)

		case CmdSubDeviceOffline:
			t.CmdType = c
			res, err = h.onSubDeviceOffline(t, sess, body)

			//		case CmdSyncState:
			//			GMsgBusManager.Push2Bus(0, nil, t.Msg)

		default:
			glog.Warningf("invalid command type %v", c)
			if sess != nil {
				locker.Unlock()
			}
			// don't reply on wrong msgid

			//b := make([]byte, 4)
			//binary.LittleEndian.PutUint32(b, uint32(DAckBadCmd))
			//output = append(output, b...)

			//err = computeCheck(output)
			//if err == nil {
			//	h.Server.Send(t.Peer, output)
			//} else {
			//	if glog.V(1) {
			//		glog.Warningf("[handle] check message failed: %v", err)
			//	}
			//}
			return nil
		}
		if sess != nil {
			gUdpSessions.SaveSession(sid, sess)
			locker.Unlock()
		}
		if err != nil {
			if glog.V(1) {
				glog.Errorf("[handle] cmd: %X, error: %v", c, err)
			}
		}
		if c != CmdGetToken {
			copy(res[4:20], t.Msg[bodyIndex:bodyIndex+16])
			copy(res[4:20], sid[:])
		}
		if res != nil {
			output = append(output, res...)
		}

		output[FrameHeaderLen] |= (msgs.FlagAck | msgs.FlagRead)
		binary.LittleEndian.PutUint16(output[FrameHeaderLen+6:], uint16(len(res)))
		output[FrameHeaderLen+8] = msgs.ChecksumHeader(output, FrameHeaderLen+8)
		output[FrameHeaderLen+9] = msgs.ChecksumHeader(output[FrameHeaderLen+10:], 2+len(res))
		h.Server.Send(t.Peer, output)

	} else if op == 0x3 {
		if mlen < FrameHeaderLen+kSidLen+FrameHeaderLen+DataHeaderLen {
			return fmt.Errorf("[protocol] invalid message length for protocol")
		}
		packNum := binary.LittleEndian.Uint16(t.Msg[2:4])
		//		bodyLen := int(binary.LittleEndian.Uint16(t.Msg[FrameHeaderLen+kSidLen+FrameHeaderLen+6:]))
		// discard msg if found checking error
		//		if t.Msg[FrameHeaderLen+kSidLen+FrameHeaderLen+8] != msgs.ChecksumHeader(t.Msg, FrameHeaderLen+kSidLen+FrameHeaderLen+8) {
		//			return fmt.Errorf("checksum header error")
		//		}

		// check data body
		//		if t.Msg[FrameHeaderLen+kSidLen+FrameHeaderLen+9] != msgs.ChecksumHeader(t.Msg[FrameHeaderLen+kSidLen+FrameHeaderLen+10:], 2+bodyLen) {
		//			return fmt.Errorf("checksum data error")
		//		}

		var (
			sess   *UdpSession
			sid    *uuid.UUID
			err    error
			locker Locker
		)

		//bodyIndex = FrameHeaderLen + DataHeaderLen
		//if bodyLen != len(t.Msg[bodyIndex:]) {
		//	return fmt.Errorf("wrong body length in data header: %d != %d", bodyLen, len(t.Msg[bodyIndex:]))
		//}
		//		body = t.Msg[bodyIndex : bodyIndex+bodyLen]

		sid, err = uuid.Parse(t.Msg[FrameHeaderLen : FrameHeaderLen+kSidLen])
		if err != nil {
			return fmt.Errorf("parse session id error: %v", err)
		}
		locker = NewDeviceSessionLocker(sid.String())
		err = locker.Lock()
		if err != nil {
			return fmt.Errorf("lock session id [%s] failed: %v", sid, err)
		}
		sess, err = gUdpSessions.GetSession(sid)
		if err != nil {
			locker.Unlock()
			return fmt.Errorf("[ForwardMsg] sid: [%v], error: %v", sid, err)
		}
		err = sess.VerifySession(packNum)
		if err != nil {
			locker.Unlock()
			return fmt.Errorf("[ForwardMsg] verify session error: %v", err)
		}

		toId := int64(binary.LittleEndian.Uint64(t.Msg[8:16]))
		srcId := int64(binary.LittleEndian.Uint64(t.Msg[16:24]))

		// check binded ids
		destIds := sess.CalcDestIds(toId)

		locker.Unlock()

		if glog.V(3) {
			glog.Infof("[udp|received] %d -> %d udp, calc to: %v, data: (len: %d)%v...", srcId, toId, destIds, len(t.Msg), t.Msg)
		} else if glog.V(2) {
			glog.Infof("[udp|received] %d -> %d udp, calc to: %v, data: (len: %d)%v...", srcId, toId, sess.BindedUsers, destIds, len(t.Msg), t.Msg[0:kDstIdEnd])
		}

		GMsgBusManager.Push2Bus(srcId, destIds, t.Msg)
	}
	return nil
}