Пример #1
0
func (c *NothingCommand) Handle(packet *core.Packet, service *core.Service) error {
	utils.Debug("NOTHING packet: ", packet)
	if service == nil {
		return errors.New("NOTHING error: There is no service for this serviceId connected.")
	}
	return nil
}
Пример #2
0
func (r *PacketReader) SetRecovering(conn *net.TCPConn, recoverMessage *Packet) {
	if !r.master.IsValidConnection(conn) {
		utils.Debug("PacketReader: Can't send recover message, because the connection is not valid:", conn)
		return
	}
	_, err := conn.Write(recoverMessage.Prepare())
	if err != nil {
		utils.Debug("PacketReader: Error sending recover message:", err)
		netOpError, ok := err.(*net.OpError)
		if err == io.EOF || err.Error()[0:11] == "WSARecv tcp" || (ok && (netOpError.Err.Error() == "use of closed network connection" || netOpError.Err.Error() == "read: connection reset by peer")) {
			r.master.SetValidConnection(conn, false)
		}
		return
	}
	r.recovering[conn] = recoverMessage.Prepare()
	utils.Debug("PacketReader: Connection", conn, "must recover with this message:", recoverMessage)
}
Пример #3
0
func HandleIndex(w http.ResponseWriter, r *http.Request) {
	utils.Debug(r, "Index")
	err := views.IndexTemplate.Execute(w, nil)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
Пример #4
0
func (c *DisconnectCommand) Handle(packet *core.Packet, service *core.Service) error {
	utils.Debug("DISCONNECT packet: ", packet)
	if service == nil {
		return errors.New("DISCONNECT error: There is no service for this serviceId connected.")
	}
	if len(packet.Content) > 0 {
		return errors.New("DISCONNECT error: The packet data is too long.")
	}
	return c.GetMaster().DisconnectService(service)
}
Пример #5
0
func (c *UnsubscribeCommand) Handle(packet *core.Packet, service *core.Service) error {
	utils.Debug("UNSUBSCRIBE packet: ", packet)
	if service == nil {
		return errors.New("UNSUBSCRIBE error: There is no service for this serviceId connected.")
	}
	if len(packet.Content) <= 0 {
		return errors.New("UNSUBSCRIBE error: The packet data is too short.")
	}
	for i := 0; i < len(packet.Content); i++ {
		c.GetMaster().SubscriptionMap.RemoveSubscription(service, utils.ByteToUint8(packet.Content[i]))
	}
	return nil
}
Пример #6
0
func (c *SyncTimeCommand) Handle(packet *core.Packet, service *core.Service) error {
	utils.Debug("SYNC_TIME packet: ", packet)
	if service == nil {
		return errors.New("SYNC_TIME error: There is no service for this serviceId connected.")
	}
	timeBytes, err := time.Now().MarshalText()
	if err != nil {
		return err
	}
	answerPacket := core.ConstructPacket(packet.Sender, packet.ServiceId, packet.PacketType, packet.PacketId, []byte{})
	answerPacket.AppendContent(timeBytes)
	service.Write(answerPacket)
	return nil
}
Пример #7
0
func (s *Service) Write(packet *Packet) {
	if !s.master.IsValidConnection(s.Connection) {
		return
	}
	if config.DEBUG {
		utils.Debug(s.Connection.LocalAddr(), "->", s.Connection.RemoteAddr(), "Len:", packet.ContentLength, "Packet:", packet)
	} else {
		utils.Print(s.Connection.LocalAddr(), "->", s.Connection.RemoteAddr(), "Len:", packet.ContentLength)
	}
	_, err := s.Connection.Write(packet.Prepare())
	if err != nil {
		netOpError, ok := err.(*net.OpError)
		if err == io.EOF || err.Error()[0:11] == "WSARecv tcp" || (ok && (netOpError.Err.Error() == "use of closed network connection" || netOpError.Err.Error() == "read: connection reset by peer")) {
			s.master.RemoveValidConnection(s.Connection)
		}
	}
}
Пример #8
0
func (master *Master) ConnectService(service *Service) error {
	if service == nil {
		return errors.New("The service can't be nil.")
	}
	serviceId := service.ServiceId
	if service2, found := master.ServiceById[serviceId]; found {
		if service2 == service {
			return errors.New("The service is connected already.")
		} else {
			return errors.New("Another service is connected as this serviceId already.")
		}
	}
	master.Services = append(master.Services, service)
	master.ServiceById[service.ServiceId] = service
	master.LastPacketId[service.ServiceId] = 0
	utils.Debug("Master: Service connected:", service)
	return nil
}
Пример #9
0
//example of using a model to save a User
func HandleSaveUser(w http.ResponseWriter, r *http.Request) {
	company := r.FormValue("company")
	email := r.FormValue("email")
	admin := utils.GetCheckboxAsBool(r.FormValue("admin"))
	user := models.User{
		Company: company,
		Email:   email,
		Admin:   admin,
		Enabled: true,
		Created: time.Now(),
	}

	err := models.SaveUser(appengine.NewContext(r), &user)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	} else {
		utils.Debug(r, "Saved User "+company+", "+email+", Admin: "+strconv.FormatBool(admin))
	}
}
Пример #10
0
func (c *ListServicesCommand) Handle(packet *core.Packet, service *core.Service) error {
	utils.Debug("LIST_SERVICES packet: ", packet)
	if service == nil {
		return errors.New("LIST_SERVICES error: There is no service for this serviceId connected.")
	}
	if len(packet.Content) > 0 {
		return errors.New("LIST_SERVICES error: The packet data is too long.")
	}

	answerPacket := core.ConstructPacket(packet.Sender, packet.ServiceId, packet.PacketType, packet.PacketId, []byte{})
	services := c.GetMaster().Services
	for _, service := range services {
		answerPacket.AppendContent(utils.UintToByte(uint(len(service.Name)+1), 2))
		answerPacket.AppendContent(utils.UintToByte(uint(service.ServiceId), 1))
		answerPacket.AppendContent([]byte(service.Name))
	}
	service.Write(answerPacket)
	return nil
}
Пример #11
0
func (c *ConnectCommand) Handle(packet *core.Packet, service *core.Service) error {
	utils.Debug("CONNECT packet: ", packet)
	if service != nil {
		return errors.New("CONNECT error: There is already a service for this serviceId connected.")
	}
	rawData := packet.Content
	dataLength := len(rawData)
	if dataLength < 2 {
		return errors.New("CONNECT error: The packet data is too short.")
	}
	serviceName := ""
	tunnelHost := ""
	tunnelPorts := make(map[uint8]uint)
	lenServiceName := int(utils.ByteToUint8(rawData[0]))
	if dataLength < 2+lenServiceName {
		return errors.New("CONNECT error: The packet data is too short. (serviceName)")
	}
	lenTunnelHost := int(utils.ByteToUint8(rawData[lenServiceName+1]))
	if dataLength < 2+lenServiceName+lenTunnelHost {
		return errors.New("CONNECT error: The packet data is too short. (tunnelHost)")
	}
	lenTunnelPorts := dataLength - lenServiceName - lenTunnelHost - 2
	if lenTunnelPorts%3 != 0 {
		return errors.New("CONNECT error: The packet data length is not valid. (tunnelPorts)")
	}

	if lenServiceName > 0 {
		serviceName = string(rawData[1 : lenServiceName+1])
	}
	if lenTunnelHost > 0 {
		tunnelHost = string(rawData[lenServiceName+2 : lenServiceName+2+lenTunnelHost])
	}
	for i := 0; i*3 < lenTunnelPorts; i++ {
		pos := lenServiceName + lenTunnelHost + 2 + (i * 3)
		tunnelPorts[utils.ByteToUint8(rawData[pos])] = utils.ByteToUint(rawData[pos+1 : pos+3])
	}
	return c.GetMaster().ConnectService(core.NewService(c.GetMaster(), packet.ServiceId, serviceName, packet.Sender, tunnelHost, tunnelPorts))
}
Пример #12
0
func (master *Master) DisconnectService(service *Service) error {
	if service == nil {
		return errors.New("The service can't be nil.")
	}
	serviceId := service.ServiceId
	if service2, found := master.ServiceById[serviceId]; found {
		if service2 == service {
			for index, service3 := range master.Services {
				if service3 == service {
					master.Services = append(master.Services[:index], master.Services[index+1:]...)
				}
			}
			delete(master.ServiceById, serviceId)
			delete(master.LastPacketId, serviceId)
			// Unsubscribe all active subscriptions
			for i := 0; i < 256; i++ {
				master.SubscriptionMap.RemoveSubscription(service, uint8(i))
			}
			utils.Debug("Master: Service disconnected:", service)
			return nil
		}
	}
	return errors.New("The service isn't connected.")
}
Пример #13
0
func (c *AskTunnelCommand) Handle(packet *core.Packet, service *core.Service) error {
	utils.Debug("ASK_TUNNEL packet: ", packet)
	if service == nil {
		return errors.New("ASK_TUNNEL error: There is no service for this serviceId connected.")
	}
	if len(packet.Content) <= 0 {
		return errors.New("ASK_TUNNEL error: The packet data is too small.")
	}
	answerPacket := core.ConstructPacket(packet.Sender, packet.ServiceId, packet.PacketType, packet.PacketId, []byte{})
	services := c.GetMaster().Services
	for i := 0; i < len(packet.Content); i++ {
		tunnelRequest := utils.ByteToUint8(packet.Content[i])
		for _, service := range services {
			if port, ok := service.TunnelPorts[packet.ServiceId]; ok && service.ServiceId == tunnelRequest {
				answerPacket.AppendContent(utils.UintToByte(uint(len(service.TunnelHost)+3), 2))
				answerPacket.AppendContent(utils.UintToByte(uint(service.ServiceId), 1))
				answerPacket.AppendContent(utils.UintToByte(port, 2))
				answerPacket.AppendContent([]byte(service.TunnelHost))
			}
		}
	}
	service.Write(answerPacket)
	return nil
}
Пример #14
0
func (master *Master) Listen() {
	utils.Debug("Master: Now listening for TCP connections.")

	running := true

	// fetch new tcp connections parallel
	go func() {

	LoopConnector:
		for running {
			select {
			case <-master.quit:
				running = false
				break LoopConnector
			default:
				conn, err := master.listener.AcceptTCP()
				if err != nil {
					if err == io.EOF || err.Error()[0:11] != "WSARecv tcp" {
						running = false
						break LoopConnector
					}
					netOpError, ok := err.(*net.OpError)
					if ok && (netOpError.Err.Error() == "use of closed network connection" || netOpError.Err.Error() == "read: connection reset by peer") {
						running = false
						break LoopConnector
					}
					utils.Debug("Master: Error accepting new TCP connection:", err)
					continue
				}
				master.newConnections <- conn
			}
		}
		utils.Debug("Master: LoopConnector stopped.")

	}()

LoopWorker:
	for running {
		select {
		case <-master.quit:
			utils.Debug("Master: LoopWorker stopped.")
			break LoopWorker
		case conn := <-master.newConnections:
			master.AddValidConnection(conn)
			go master.packetReader.Listen(conn)
		case conn := <-master.deadConnections:
			master.RemoveValidConnection(conn)
			services := master.Services
			for _, service := range services {
				if service.Connection == conn {
					master.DisconnectService(service)
				}
			}
		case message := <-master.messages:
			if !message.IsData() {
				service := master.ServiceById[message.ServiceId]
				err := master.GetCommandInterpreter().Handle(message, service)
				if err != nil {
					utils.Debug("Master WARN: CommandInterpreter couldn't handle packet:", err)
				}
			}
			subscribers := master.SubscriptionMap.GetServicesForPacketType(message.PacketType)
			for _, service := range subscribers {
				service.Write(message)
			}
		}
	}
	utils.Print("Master stopped.")
}
Пример #15
0
func (r *PacketReader) Read(conn *net.TCPConn) (*Packet, error) {
	headerBuffer := make([]byte, 8)
	n, err := conn.Read(headerBuffer)
	if err != nil {
		return nil, err
	}
	if n != 8 {
		return nil, errors.New("Packet header was " + strconv.Itoa(n) + " bytes.")
	}
	contentLength := int(utils.ByteToUint(headerBuffer[0:3])) - 5
	if contentLength < 0 {
		return nil, errors.New("Packet ContentLength is a negative number. ContentLength - 5 Header bytes: " + strconv.Itoa(contentLength))
	}
	serviceId := utils.ByteToUint8(headerBuffer[3])
	packetId := utils.ByteToUint(headerBuffer[5:8])
	service := r.master.ServiceById[serviceId]

	// Don't trust the packet serviceId, if the connection is already connected to the master,
	// instead use the connected serviceId information
	setServiceId := serviceId
	for sId, service := range r.master.ServiceById {
		if service.Connection == conn {
			setServiceId = sId
		}
	}
	if setServiceId != serviceId {
		utils.Debug("PacketReader: WARN: The serviceId of the connected service for this Connection (", conn, ") does not match the packet serviceId", serviceId, ". Overriding the packet serviceId for recover messages.")
	}

	recoverMessage := ConstructPacket(conn, setServiceId, PACKETTYPE_NOTHING, packetId, []byte{})
	if contentLength > config.MAX_PACKET_SIZE {
		r.SetRecovering(conn, recoverMessage)
		return nil, errors.New("Packet header indicates too long packet: " + strconv.Itoa(contentLength))
	}
	if service != nil && service.Connection != conn {
		r.SetRecovering(conn, recoverMessage)
		return nil, errors.New("packet sender connection is not origin service connection")
	}
	if lastId, found := r.master.LastPacketId[serviceId]; found {
		if packetId <= lastId {
			r.SetRecovering(conn, recoverMessage)
			return nil, errors.New("Packet header packetId is too small: " + strconv.Itoa(int(packetId)) + " <= " + strconv.Itoa(int(lastId)))
		}
	}
	r.master.LastPacketId[serviceId] = packetId

	if contentLength <= 0 {
		return NewPacket(conn, headerBuffer)
	}

	contentBuffer := make([]byte, contentLength)
	n, err = conn.Read(contentBuffer)
	if err != nil {
		if err != io.EOF && err.Error()[0:11] != "WSARecv tcp" {
			netOpError, ok := err.(*net.OpError)
			if !ok || (netOpError.Err.Error() != "use of closed network connection" && netOpError.Err.Error() != "read: connection reset by peer") {
				r.SetRecovering(conn, recoverMessage)
			}
		}
		return nil, err
	}
	if n != contentLength {
		r.SetRecovering(conn, recoverMessage)
		return nil, errors.New("Packet content does not fit into the defined content buffer size exactly: " + strconv.Itoa(n) + " != " + strconv.Itoa(contentLength))
	}
	return NewPacket(conn, append(headerBuffer, contentBuffer...))
}
Пример #16
0
func (r *PacketReader) Listen(conn *net.TCPConn) {

	for _, connection := range r.connections {
		if connection == conn {
			utils.Debug("PacketReader: Already listening on Connection", conn, ". Skipped enabling another listener.")
			return
		}
	}
	r.connections = append(r.connections, conn)

	utils.Debug("PacketReader: Now listening on Connection:", conn)
	r.recovering[conn] = []byte{}
	defer conn.Close()
LoopListen:
	for r.master.IsValidConnection(conn) {
		select {
		case <-r.quit:
			utils.Debug("PacketReader: LoopListen stopped. (Quit)", conn)
			break LoopListen
		default:
			if len(r.recovering[conn]) > 0 {
				r.Recover(conn)
				if !r.master.IsValidConnection(conn) {
					utils.Debug("PacketReader: LoopListen stopped. (Recovering failed)", conn)
					r.master.deadConnections <- conn
					break LoopListen
				}
			} else {
				packet, err := r.Read(conn)
				if err != nil {
					netOpError, ok := err.(*net.OpError)
					if err == io.EOF || err.Error()[0:11] == "WSARecv tcp" || (ok && netOpError.Err.Error() == "read: connection reset by peer") {
						r.master.SetValidConnection(conn, false)
						r.master.deadConnections <- conn
						utils.Debug("PacketReader: LoopListen stopped. (Client disconnected)", conn)
						break LoopListen
					}
					if ok && netOpError.Err.Error() == "use of closed network connection" {
						r.master.SetValidConnection(conn, false)
						r.master.deadConnections <- conn
						utils.Debug("PacketReader: LoopListen stopped. (Lost Connection)", conn)
						break LoopListen
					}
					utils.Debug("PacketReader: Error reading a packet for Connection", conn, ":", err)
					continue
				}
				if config.DEBUG {
					utils.Debug(conn.RemoteAddr(), "->", conn.LocalAddr(), "Len:", packet.ContentLength, "Packet:", packet)
				} else {
					utils.Print(conn.RemoteAddr(), "->", conn.LocalAddr(), "Len:", packet.ContentLength)
				}
				r.master.NewMessage(packet)
			}
		}
	}
	for index, connection := range r.connections {
		if connection == conn {
			r.connections = append(r.connections[:index], r.connections[index+1:]...)
			break
		}
	}
	delete(r.recovering, conn)
	utils.Debug("PacketReader stopped listening on Connection:", conn)
}
Пример #17
0
func (r *PacketReader) Recover(conn *net.TCPConn) {
	recoverBuffer := make([]byte, 4096)
	recovered := false

LoopRecovering:
	for !recovered {
		if !r.master.IsValidConnection(conn) {
			break LoopRecovering
		}
		n, err := conn.Read(recoverBuffer)
		if err == nil && n < 8 {
			// to few bytes, next try
			continue
		}
		if err != nil {
			netOpError, ok := err.(*net.OpError)
			if err == io.EOF || err.Error()[0:11] == "WSARecv tcp" || (ok && netOpError.Err.Error() == "read: connection reset by peer") {
				utils.Debug("PacketReader: Recovering stopped (Client disconnected) on Connection", conn)
				r.master.SetValidConnection(conn, false)
				break LoopRecovering
			}
			if ok && netOpError.Err.Error() == "use of closed network connection" {
				utils.Debug("PacketReader: Recovering stopped (Lost Connection) on Connection", conn)
				r.master.SetValidConnection(conn, false)
				break LoopRecovering
			}

			_, err := conn.Write(r.recovering[conn])
			if err != nil {
				utils.Debug("PacketReader: Error sending recover message:", err)
				netOpError, ok := err.(*net.OpError)
				if err == io.EOF || err.Error()[0:11] == "WSARecv tcp" || (ok && (netOpError.Err.Error() == "use of closed network connection" || netOpError.Err.Error() == "read: connection reset by peer")) {
					r.master.SetValidConnection(conn, false)
				}
				// Break anyway, but keep the connection valid
				// if wrong
				break LoopRecovering
			}

			utils.Debug("PacketReader: Recovering not successful, continue.")
			continue
		}

		recoverBufferStr := []uint8{}
		for _, b := range recoverBuffer {
			recoverBufferStr = append(recoverBufferStr, utils.ByteToUint8(b))
		}
		recovered = true
		for i := 1; recovered && i <= 8; i++ {
			if r.recovering[conn][8-i] != recoverBuffer[n-i] {
				recovered = false
			}
		}
	}
	r.recovering[conn] = []byte{}
	if recovered && r.master.IsValidConnection(conn) {
		utils.Debug("PacketReader: Recovering successful on Connection", conn)
	} else {
		utils.Debug("PacketReader: Recovering failed on Connection", conn)
	}
}
Пример #18
0
func HandleAdmin(w http.ResponseWriter, r *http.Request) {
	utils.Debug(r, "Handle Admin")
}