func NewServer(port int, local_ip string, key []byte) (*Server, error) { ip := net.ParseIP(local_ip) log.Printf("Creating TUN device") tun, err := tun.NewTun(DeviceNameServer, local_ip) if err != nil { return nil, err } addr, err := net.ResolveUDPAddr("udp", ":"+strconv.Itoa(port)) if err != nil { tun.Close() return nil, err } log.Printf("Listening UDP connections on %s.", addr.String()) conn, err := net.ListenUDP("udp", addr) if err != nil { tun.Close() return nil, err } return &Server{ tun, conn, NewSessionTable(ip), key, }, nil }
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 }