Beispiel #1
0
func (s *Server) handleTun(err_chan chan error) {
	defer s.device.Close()

	for {
		pkt, err := s.device.Read()
		if err != nil {
			err_chan <- err
			return
		}

		dst_ip := binary.BigEndian.Uint32(pkt[16:20])
		addr, err := s.sessionTable.Lookup(dst_ip)

		if err != nil {
			err_chan <- err
			return
		}

		msg := &message.Message{
			Kind: message.Message_DATA.Enum(),
			Data: pkt,
		}

		data, err := proto.Marshal(msg)

		if err != nil {
			err_chan <- err
			return
		}

		data, err = crypto.Encrypt(s.secretKey, data)
		if err != nil {
			err_chan <- err
			return
		}

		_, err = s.listenerConnection.WriteToUDP(data, addr)

		if err != nil {
			err_chan <- err
			return
		}
	}
}
Beispiel #2
0
func (c *Client) handleTun(err_chan chan error) {
	defer c.device.Close()
	for {
		pkt, err := c.device.Read()

		log.Printf("%s -> %s", c.device.String(), c.serverConnection.RemoteAddr().String())

		if err != nil {
			err_chan <- err
			return
		}

		msg := &message.Message{
			Kind: message.Message_DATA.Enum(),
			Data: pkt,
		}

		data, err := proto.Marshal(msg)
		if err != nil {
			err_chan <- err
			return
		}

		data, err = crypto.Encrypt(c.secretKey, data)
		if err != nil {
			err_chan <- err
			return
		}

		_, err = c.serverConnection.Write(data)
		if err != nil {
			err_chan <- err
			return
		}
	}
}
Beispiel #3
0
func (s *Server) handleUDP(err_chan chan error) {
	defer s.listenerConnection.Close()

	for {
		buf := make([]byte, 2000)
		n, addr, err := s.listenerConnection.ReadFromUDP(buf)
		if err != nil {
			err_chan <- err
			return
		}
		buf = buf[:n]

		buf, err = crypto.Decrypt(s.secretKey, buf)
		if err != nil {
			err_chan <- err
			return
		}

		msg := &message.Message{}
		err = proto.Unmarshal(buf, msg)
		if err != nil {
			err_chan <- err
			return
		}

		switch *msg.Kind {
		case message.Message_REQUEST:
			ip := s.sessionTable.NewClient(addr)

			data := make([]byte, 4)
			binary.BigEndian.PutUint32(data, ip)

			msg = &message.Message{
				Kind: message.Message_ACCEPT.Enum(),
				Data: data,
			}

			data, err = proto.Marshal(msg)
			if err != nil {
				err_chan <- err
				return
			}

			data, err = crypto.Encrypt(s.secretKey, data)
			if err != nil {
				err_chan <- err
				return
			}

			_, err = s.listenerConnection.WriteToUDP(data, addr)
			if err != nil {
				err_chan <- err
				return
			}

		case message.Message_DATA:
			pkt := msg.Data

			err = s.device.Write(pkt)

			if err != nil {
				err_chan <- err
				return
			}

		default:
			err_chan <- errors.New("Unknown message type.")
			return
		}
	}
}
Beispiel #4
0
func (c *Client) init() error {
	msg := &message.Message{
		Kind: message.Message_REQUEST.Enum(),
	}

	log.Printf("Sending request to %s.", c.serverConnection.RemoteAddr().String())

	data, err := proto.Marshal(msg)
	if err != nil {
		return err
	}

	data, err = crypto.Encrypt(c.secretKey, data)
	if err != nil {
		return err
	}

	success := false
	buf := make([]byte, 1600)

	for !success {
		_, err = c.serverConnection.Write(data)
		if err != nil {
			return err
		}

		c.serverConnection.SetReadDeadline(time.Now().Add(5 * time.Second))
		n, err := c.serverConnection.Read(buf)
		c.serverConnection.SetReadDeadline(time.Time{})

		if err != nil {
			log.Printf("Read error: %v. Reconnecting...", err)
			continue
		}

		buf = buf[:n]
		success = true
	}

	buf, err = crypto.Decrypt(c.secretKey, buf)
	if err != nil {
		return err
	}

	msg = &message.Message{}
	err = proto.Unmarshal(buf, msg)

	if *msg.Kind != message.Message_ACCEPT {
		return errors.New("Unexpected message type.")
	}

	var local_ip net.IP
	local_ip = msg.Data
	log.Printf("Client IP %s assigned.", local_ip.String())

	c.device, err = tun.NewTun(DeviceNameClient, local_ip.String())
	if err != nil {
		return err
	}

	local_ip[3] = 0x1
	c.gatewayAddress, err = util.DefaultGateway()
	if err != nil {
		return err
	}
	err = util.SetGatewayForHost(c.gatewayAddress, c.serverAddress)
	if err != nil {
		return err
	}
	err = util.ClearGateway()
	if err != nil {
		return err
	}
	err = util.SetDefaultGateway(local_ip.String())
	if err != nil {
		return err
	}

	return nil
}