无法使用Toyvpn启动VPN

时间:2014-05-16 20:09:09

标签: android sockets network-programming vpn datagram

我会尝试尽可能具有描述性 我是android的新手,我正在制作一个Android应用程序 在该应用程序中,我希望能够看到从移动设备发出的HTTP请求的地址(在他们前往的网站上)。 所以我环顾四周,我发现要做到这一点,我需要使用VPN和Android 4.0+有一个由谷歌提供的VPNService使用ToyVPNService实现 所以我得到了这项服务,并开始改变它,所以我可以使用它而无需使用服务器 我想按如下方式使用VPN: 1 - 捕获HTTP请求 2 - 阅读他们的目的地 3 - 将它们重新发送回原位

所以我接受了VPNService,我开始修改它,以便我不需要一个真正的服务器 这是我使用

的代码
    package com.example.testingservice;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.net.VpnService;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.Enumeration;
public class SO1 extends VpnService implements Handler.Callback, Runnable {
private static final String TAG = "ToyVpnService";

private Handler mHandler;
private Thread mThread;

private ParcelFileDescriptor mInterface;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // The handler is only used to show messages.
    if (mHandler == null) {
        mHandler = new Handler(this);
    }

    // Stop the previous session by interrupting the thread.
    if (mThread != null) {
        mThread.interrupt();
    }

    // Start a new session by creating a new thread.
    mThread = new Thread(this, "ToyVpnThread");
    mThread.start();
    return START_STICKY;
}

@Override
public void onDestroy() {
    if (mThread != null) {
        mThread.interrupt();
    }
}

@Override
public boolean handleMessage(Message message) {
    if (message != null) {
        Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show();
    }
    return true;
}

@Override
public synchronized void run() {
    Log.i(TAG,"running vpnService");
    try {
        runVpnConnection();
    } catch (Exception e) {
        e.printStackTrace();
        //Log.e(TAG, "Got " + e.toString());
    } finally {
        try {
            mInterface.close();
        } catch (Exception e) {
            // ignore
        }
        mInterface = null;

        mHandler.sendEmptyMessage(R.string.disconnected);
        Log.i(TAG, "Exiting");
    }
}

private boolean runVpnConnection() throws Exception {

    configure();

    FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());

    // Allocate the buffer for a single packet.
    ByteBuffer packet = ByteBuffer.allocate(32767);

    // We keep forwarding packets till something goes wrong.
    while (true) {
        // Assume that we did not make any progress in this iteration.
        boolean idle = true;

        // Read the outgoing packet from the input stream.
        int length = in.read(packet.array());
        if (length > 0) {

            Log.i(TAG,"************new packet");
            System.exit(-1);
            while (packet.hasRemaining()) {
                Log.i(TAG,""+packet.get());
                //System.out.print((char) packet.get());
            }
            packet.limit(length);
            //  tunnel.write(packet);
            packet.clear();

            // There might be more outgoing packets.
            idle = false;
        }
        Thread.sleep(50);
    }
}

public String getLocalIpAddress()
{
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                Log.i(TAG,"****** INET ADDRESS ******");
                Log.i(TAG,"address: "+inetAddress.getHostAddress());
                Log.i(TAG,"hostname: "+inetAddress.getHostName());
                Log.i(TAG,"address.toString(): "+inetAddress.getHostAddress().toString());
                if (!inetAddress.isLoopbackAddress()) {
                    //IPAddresses.setText(inetAddress.getHostAddress().toString());
                    Log.i(TAG,"IS NOT LOOPBACK ADDRESS: "+inetAddress.getHostAddress().toString());
                    return inetAddress.getHostAddress().toString();
                } else{
                    Log.i(TAG,"It is a loopback address");
                }
            }
        }
    } catch (SocketException ex) {
        String LOG_TAG = null;
        Log.e(LOG_TAG, ex.toString());
    }

    return null;
}

private void configure() throws Exception {
    // If the old interface has exactly the same parameters, use it!
    if (mInterface != null) {
        Log.i(TAG, "Using the previous interface");
        return;
    }

    // Configure a builder while parsing the parameters.
    Builder builder = new Builder();
    String SS=getLocalIpAddress();
    builder.setMtu(1500);
  //  builder.addAddress("10.0.0.2", 24);
    builder.addAddress(SS, 24);
   // builder.addAddress(SS,24);
    builder.addRoute("0.0.0.0",0);
    try {
        mInterface.close();
    } catch (Exception e) {
        // ignore
    }

    mInterface = builder.establish();
}}

问题在于这一行

mInterface = builder.setSession("GITVPN").setConfigureIntent(mConfigureIntent).establish();

Establish返回NULL,我似乎无法使其正常工作 我认为地址有问题 我想工作它没有服务器,并且会有一个隧道读取数据包 我已经看到其他帖子说我应该将地址设置为10.0.0.2而不是外部ips(192.168.x.x),我应该添加路由(0.0.0.0,0) 然而,描述符文件保持返回null,我似乎无法修复它 任何帮助将不胜感激,如果这听起来有点重复,我感到非常抱歉,但我超级卡住,你们是我唯一的希望

3 个答案:

答案 0 :(得分:1)

如果没有与之通信的服务器并且将流量转发到互联网,则无法运行VpnService并建立VPN连接。

答案 1 :(得分:1)

检查您分配给接口的IP地址,它不应与其他适配器相同。 构建器运行的是TUN设备,它是为VPN服务创建的。 因此,应该正确设置TUN的IP地址。 让地址与他人发生冲突不是一个好主意。

另外,你提到的第3步并不容易,因为Android不支持原始套接字。

答案 2 :(得分:0)

只是为了恢复一个旧线程...

  • VpnService需要用户互动才能开始,并且在没有它的情况下无法工作
  • ToyVpnClient在屏幕上放置一个用户必须点击的按钮,一旦完成,Builder方法将返回界面

所以,让它发挥作用的步骤是; 1.在您的应用上构建一个按钮 2. onclick该按钮,调用VpnService.prepare(this);(这=您的应用内容) 3. Builder.establish()现在将返回VPN接口