Ejemplo n.º 1
0
// client and transport handler for connections.
func (s *Server) clientHandler(conn net.Conn) {
	defer conn.Close()

	c := &client{
		conn: conn,
		enc:  gob.NewEncoder(conn),
		dec:  gob.NewDecoder(conn),
	}

	// get the first client struct as a handshake
	var handshake Message
	if err := c.dec.Decode(&handshake); err != nil {
		// client disconnected before it sent the full handshake
		if err != io.EOF {
			log.Errorln(err)
		}
		return
	}
	c.Client = handshake.Client
	log.Debug("new client: %v", handshake.Client)

	if c.Version != version.Revision {
		log.Warn("mismatched miniccc version: %v", c.Version)
	}

	// Set up minitunnel, dialing the server that should be running on the
	// client's side. Data is Trunk'd via Messages.
	local, remote := net.Pipe()
	defer local.Close()
	defer remote.Close()

	go func() {
		go Trunk(remote, c.UUID, c.sendMessage)

		tunnel, err := minitunnel.Dial(local)
		if err != nil {
			log.Error("dial: %v", err)
			return
		}

		s.clientLock.Lock()
		defer s.clientLock.Unlock()

		log.Debug("minitunnel created for %v", c.UUID)
		c.tunnel = tunnel
	}()

	c.Checkin = time.Now()

	if err := s.addClient(c); err != nil {
		log.Errorln(err)
		return
	}
	defer s.removeClient(c.UUID)

	var err error

	for err == nil {
		var m Message
		if err = c.dec.Decode(&m); err == nil {
			log.Debug("new message: %v", m.Type)

			switch m.Type {
			case MESSAGE_TUNNEL:
				_, err = remote.Write(m.Tunnel)
			case MESSAGE_FILE:
				m2 := s.readFile(m.Filename)
				m2.UUID = m.UUID
				err = c.sendMessage(m2)
			case MESSAGE_CLIENT:
				s.responses <- m.Client
			case MESSAGE_COMMAND:
				// this shouldn't be sent via the client...
			default:
				err = fmt.Errorf("unknown message type: %v", m.Type)
			}
		}
	}

	if err != io.EOF && !strings.Contains(err.Error(), "connection reset by peer") {
		log.Errorln(err)
	}
}
Ejemplo n.º 2
0
// tunnel transport handler
func (c *Client) handleTunnel(server bool, stop chan bool) {
	log.Debug("handleTunnel: %v", server)

	a, b := net.Pipe()

	c.tunnelData = make(chan []byte, 1024)

	go func() {
		if server {
			var err error
			c.tunnel, err = minitunnel.Dial(a)
			if err != nil {
				log.Errorln("Dial: %v", err)
				a.Close()
				b.Close()
			}
		} else {
			go func() {
				err := minitunnel.ListenAndServe(a)
				if err != nil {
					log.Fatalln("ListenAndServe: %v", err)
				}
			}()
		}
	}()

	go func() {
		for {
			var buf = make([]byte, BUFFER_SIZE)
			n, err := b.Read(buf)
			if err != nil {
				if err != io.ErrClosedPipe {
					log.Errorln(err)
				}
				a.Close()
				b.Close()
				return
			}

			// push it up in a message
			m := &Message{
				Type:   MESSAGE_TUNNEL,
				UUID:   c.UUID,
				Tunnel: buf[:n],
			}

			c.out <- m
		}
	}()

	go func() {
		for {
			data := <-c.tunnelData
			if data == nil {
				return
			}
			_, err := b.Write(data)
			if err != nil {
				log.Errorln(err)
				a.Close()
				b.Close()
				return
			}
		}
	}()

	<-stop
	log.Debug("ron client tunnel close: %v", c.UUID)
	a.Close()
	b.Close()
	close(c.tunnelData)
}