func (c *Client) handleUDP(err_chan chan error) { defer c.serverConnection.Close() for { buf := make([]byte, 1600) n, err := c.serverConnection.Read(buf) log.Printf("%s -> %s", c.serverConnection.RemoteAddr().String(), c.device.String()) if err != nil { err_chan <- err return } buf, err = crypto.Decrypt(c.secretKey, buf[:n]) if err != nil { err_chan <- err return } msg := &message.Message{} err = proto.Unmarshal(buf, msg) if err != nil { err_chan <- err return } if *msg.Kind != message.Message_DATA { err = errors.New("Unexpected message type.") err_chan <- err return } err = c.device.Write(msg.Data) if err != nil { err_chan <- err return } } }
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 } } }
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 }