aboutsummaryrefslogtreecommitdiff
path: root/src/java/android/net/ipsec/ike/ChildSessionConfiguration.java
blob: 2ed9de2fde2bdae385d848a1e65ca770db73486a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net.ipsec.ike;

import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS;
import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK;
import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS;

import android.net.LinkAddress;

import com.android.internal.net.ipsec.ike.message.IkeConfigPayload;
import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address;
import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/** ChildSessionConfiguration represents the negotiated configuration for a Child Session. */
public final class ChildSessionConfiguration {
    private static final int IPv4_DEFAULT_PREFIX_LEN = 32;

    private final List<IkeTrafficSelector> mInboundTs;
    private final List<IkeTrafficSelector> mOutboundTs;
    private final List<LinkAddress> mInternalAddressList;

    /**
     * Construct an instance of {@link ChildSessionConfiguration}.
     *
     * <p>It is only supported to build a {@link ChildSessionConfiguration} with a Configure(Reply)
     * Payload.
     */
    public ChildSessionConfiguration(
            List<IkeTrafficSelector> inTs,
            List<IkeTrafficSelector> outTs,
            IkeConfigPayload configPayload) {
        this(inTs, outTs);

        if (configPayload.configType != IkeConfigPayload.CONFIG_TYPE_REPLY) {
            throw new IllegalArgumentException(
                    "Cannot build ChildSessionConfiguration with configuration type: "
                            + configPayload.configType);
        }

        // It is validated in IkeConfigPayload that a config reply only has at most one non-empty
        // netmask and netmask exists only when IPv4 internal address exists.
        ConfigAttributeIpv4Netmask netmaskAttr = null;
        for (ConfigAttribute att : configPayload.recognizedAttributeList) {
            if (att.attributeType == CONFIG_ATTR_INTERNAL_IP4_NETMASK && !att.isEmptyValue()) {
                netmaskAttr = (ConfigAttributeIpv4Netmask) att;
            }
        }

        for (ConfigAttribute att : configPayload.recognizedAttributeList) {
            if (att.isEmptyValue()) continue;
            switch (att.attributeType) {
                case CONFIG_ATTR_INTERNAL_IP4_ADDRESS:
                    ConfigAttributeIpv4Address addressAttr = (ConfigAttributeIpv4Address) att;
                    if (netmaskAttr != null) {
                        mInternalAddressList.add(
                                new LinkAddress(addressAttr.address, netmaskAttr.getPrefixLen()));
                    } else {
                        mInternalAddressList.add(
                                new LinkAddress(addressAttr.address, IPv4_DEFAULT_PREFIX_LEN));
                    }
                    break;
                case CONFIG_ATTR_INTERNAL_IP4_NETMASK:
                    // No action.
                    break;
                case CONFIG_ATTR_INTERNAL_IP6_ADDRESS:
                    mInternalAddressList.add(((ConfigAttributeIpv6Address) att).linkAddress);
                    break;
                default:
                    // TODO: Support DNS,Subnet and Dhcp4 attributes
            }
        }
    }

    /** Construct an instance of {@link ChildSessionConfiguration}. */
    public ChildSessionConfiguration(
            List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs) {
        mInboundTs = Collections.unmodifiableList(inTs);
        mOutboundTs = Collections.unmodifiableList(outTs);
        mInternalAddressList = new LinkedList<>();
    }

    /**
     * Returns the negotiated inbound traffic selectors.
     *
     * @return the inbound traffic selector.
     */
    public List<IkeTrafficSelector> getInboundTrafficSelectors() {
        return mInboundTs;
    }

    /**
     * Returns the negotiated outbound traffic selectors.
     *
     * @return the outbound traffic selector.
     */
    public List<IkeTrafficSelector> getOutboundTrafficSelectors() {
        return mOutboundTs;
    }

    /**
     * Returns the assigned internal addresses.
     *
     * @return assigned internal addresses, or empty list when no addresses are assigned by the
     *     remote IKE server.
     */
    public List<LinkAddress> getInternalAddressList() {
        return mInternalAddressList;
    }
}