【Android】(十二) NAT

NAT

//packages/modules/Connectivity/Tethering/src/android/net/ip/IpServer.java
//Initial 状态的转换
case CMD_TETHER_REQUESTED:
    mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
    switch (message.arg1) {
        case STATE_LOCAL_ONLY:
            maybeConfigureStaticIp((TetheringRequestParcel) message.obj);
            transitionTo(mLocalHotspotState);
            break;
        case STATE_TETHERED:
            maybeConfigureStaticIp((TetheringRequestParcel) message.obj);//********
            transitionTo(mTetheredState);
            break;
        default:
            mLog.e("Invalid tethering interface serving state specified.");
                    

当热点被创建的时候,IpServer 会接收到来自 Tethering 对象的 CMD_TETHER_REQUEST 消息,并且根据接收到消息的 arg1 成员的值选择进入 LOCAL_ONLY 或者 TETHERED 状态。只有在 TETHERED 而非 LOCAL_ONLY 时会涉及到如下 NAT 开启与否。

//packages/modules/Connectivity/Tethering/src/android/net/ip/IpServer.java
class TetheredState extends BaseServingState {
    @Override
    public void enter() {
        //...
        sendInterfaceState(STATE_TETHERED);
    }
}
private void sendInterfaceState(int newInterfaceState) {
    mServingMode = newInterfaceState;
    mCallback.updateInterfaceState(this, newInterfaceState, mLastError);
    sendLinkProperties();
}

进入状态时会调用状态的 enter 方法,向 Tethering 对象通知接口状态的改变。

//packages/modules/Connectivity/Tethering/src/com/android/networkstack/tethering/Tethering.java
private void notifyInterfaceStateChange(IpServer who, int state, int error) {
    //...
    int which;
    switch (state) {
        //...
            break;
        case IpServer.STATE_TETHERED:
        case IpServer.STATE_LOCAL_ONLY:
            which = TetherMainSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
            break;
        //...
    }
    mTetherMainSM.sendMessage(which, state, 0, who);
    sendTetherStateChangedBroadcast();
}
class InitialState extends State {
    @Override
    public boolean processMessage(Message message) {
        logMessage(this, message.what);
        switch (message.what) {
            case EVENT_IFACE_SERVING_STATE_ACTIVE: {
                //...
                handleInterfaceServingStateActive(message.arg1, who);//保证了mForwardedDownstreams不为空, upstreamWanted()为true。
                transitionTo(mTetherModeAliveState);
                break;
            }
            //其他状态...
        }
        return HANDLED;
    }
}

通过 mCallback.updateInterfaceState 调用Tethering对象的 notifyInterfaceStateChange 方法向TetherMainStateMachine发送一个 EVENT_IFACE_SERVING_STATE_ACTIVE 消息让其进入 TetherModeAliveState 状态。

//packages/modules/Connectivity/Tethering/src/com/android/networkstack/tethering/Tethering.java
public void enter() {
    //...
    if (upstreamWanted()) {
        mUpstreamWanted = true;
        mOffload.start();
        chooseUpstreamType(true);
        mTryCell = false;
    }
    //...
}
//chooseUpstreamType->notifyDownstreamsOfNewUpstreamIface
protected void notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces) {
    mCurrentUpstreamIfaceSet = ifaces;
    for (IpServer ipServer : mNotifyList) {
        ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifaces);
    }
}

其 enter() 中调用了 chooseUpstreamType ,经过一系列的调用,最终调用 notifyDownstreamsOfNewUpstreamIface 向 IpServer 发送了一个 CMD_TETHER_CONNECTION_CHANGED 信号。(处于 TetherModeAliveState 状态也可能收到 EVENT_IFACE_SERVING_STATE_ACTIVE,此时同样会向 IpServer 发送 CMD_TETHER_CONNECTION_CHANGED,此时 iface 是 mCurrentUpstreamIfaceSet)TetheringInterfaceUtils。

//packages/modules/Connectivity/Tethering/src/android/net/ip/IpServer.java
public boolean processMessage(Message message) {
            //...
    switch (message.what) {
        //...
        case CMD_TETHER_CONNECTION_CHANGED:
            final InterfaceSet newUpstreamIfaceSet = (InterfaceSet) message.obj;
            //...
            for (String removed : upstreamInterfacesRemoved(newUpstreamIfaceSet)) {
                cleanupUpstreamInterface(removed);
            }
            final Set<String> added = upstreamInterfacesAdd(newUpstreamIfaceSet);
            //...
            for (String ifname : added) {
                //...
                mNetd.tetherAddForward(mIfaceName, ifname);
                //...
            }
            break;
        //...
    }
    return true;
}

此时 IpServer 处于 TETHERED 状态,正常处理 CMD_TETHER_CONNECTION_CHANGED 信号,此时就调用NetdService 来做NAT。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值