aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/service/netaddr/NetworkAddressManagerService.java
blob: 19b68d55db695dfa14aa76ef6a132e340caeb851 (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/*
 * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Copyright @ 2015 Atlassian Pty Ltd
 *
 * 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 net.java.sip.communicator.service.netaddr;

import java.io.*;
import java.net.*;

import net.java.sip.communicator.service.netaddr.event.*;

import org.ice4j.ice.*;
import org.ice4j.ice.harvest.*;

/**
 * The NetworkAddressManagerService takes care of problems such as
 * @author Emil Ivov
 */
public interface NetworkAddressManagerService
{
    /**
     * The default number of binds that a <tt>NetworkAddressManagerService</tt>
     * implementation should execute in case a port is already bound to (each
     * retry would be on a different port).
     */
    public static final int BIND_RETRIES_DEFAULT_VALUE = 50;

    /**
     * The name of the property containing number of binds that a
     * <tt>NetworkAddressManagerService</tt> implementation should execute in
     * case a port is already bound to (each retry would be on a different
     * port).
     */
    public static final String BIND_RETRIES_PROPERTY_NAME
        = "net.java.sip.communicator.service.netaddr.BIND_RETRIES";

    /**
     * Returns an InetAddress instance that represents the localhost, and that
     * a socket can bind upon or distribute to peers as a contact address.
     * <p>
     * This method tries to make for the ambiguity in the implementation of the
     * InetAddress.getLocalHost() method.
     * (see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037).
     * <p>
     * To put it briefly, the issue is about choosing a local source
     * address to bind to or to distribute to peers. It is possible and even
     * quite probable to expect that a machine may dispose with multiple
     * addresses and each of them may be valid for a specific destination.
     * Example cases include:
     * <p>
     * 1) A dual stack IPv6/IPv4 box. <br>
     * 2) A double NIC box with a leg on the Internet and another one in a
     * private LAN <br>
     * 3) In the presence of a virtual interface over a VPN or a MobileIP(v6)
     * tunnel.
     * <p>
     * In all such cases a source local address needs to be chosen according to
     * the intended destination and after consulting the local routing table.
     * <p>
     * @param intendedDestination the address of the destination that we'd like
     * to access through the local address that we are requesting.
     *
     * @return an InetAddress instance representing the local host, and that
     * a socket can bind upon or distribute to peers as a contact address.
     */
    public InetAddress getLocalHost(InetAddress intendedDestination);

    /**
     * Tries to obtain a mapped/public address for the specified port. If the
     * STUN lib fails, tries to retrieve localhost, if that fails too, returns
     * null.
     *
     * @param intendedDestination the destination that we'd like to use this
     * address with.
     * @param port the port whose mapping we are interested in.
     *
     * @return a public address corresponding to the specified port or null if
     * all attempts to retrieve such an address have failed.
     *
     * @throws IOException if an error occurs while the underlying resolver lib
     * is using sockets.
     * @throws BindException if the port is already in use.
     */
    public InetSocketAddress getPublicAddressFor(
                                            InetAddress intendedDestination,
                                            int port)
        throws IOException,
               BindException;

    /**
     * Returns the hardware address (i.e. MAC address) of the specified
     * interface name.
     *
     * @param iface the <tt>NetworkInterface</tt>
     * @return array of bytes representing the layer 2 address
     */
    public byte[] getHardwareAddress(NetworkInterface iface);

    /**
     * Creates a <tt>DatagramSocket</tt> and binds it to on the specified
     * <tt>localAddress</tt> and a port in the range specified by the
     * <tt>minPort</tt> and <tt>maxPort</tt> parameters. We first try to bind
     * the newly created socket on the <tt>preferredPort</tt> port number and
     * then proceed incrementally upwards until we succeed or reach the bind
     * retries limit. If we reach the <tt>maxPort</tt> port number before the
     * bind retries limit, we will then start over again at <tt>minPort</tt>
     * and keep going until we run out of retries.
     *
     * @param laddr the address that we'd like to bind the socket on.
     * @param preferredPort the port number that we should try to bind to first.
     * @param minPort the port number where we should first try to bind before
     * moving to the next one (i.e. <tt>minPort + 1</tt>)
     * @param maxPort the maximum port number where we should try binding
     * before giving up and throwinG an exception.
     *
     * @return the newly created <tt>DatagramSocket</tt>.
     *
     * @throws IllegalArgumentException if either <tt>minPort</tt> or
     * <tt>maxPort</tt> is not a valid port number.
     * @throws IOException if an error occurs while the underlying resolver lib
     * is using sockets.
     * @throws BindException if we couldn't find a free port between
     * <tt>minPort</tt> and <tt>maxPort</tt> before reaching the maximum allowed
     * number of retries.
     */
    public DatagramSocket createDatagramSocket(InetAddress laddr,
                                               int         preferredPort,
                                               int         minPort,
                                               int         maxPort)
        throws IllegalArgumentException,
               IOException,
               BindException;

    /**
     * Adds new <tt>NetworkConfigurationChangeListener</tt> which will
     * be informed for network configuration changes.
     * @param listener the listener.
     */
    public void addNetworkConfigurationChangeListener(
        NetworkConfigurationChangeListener listener);

    /**
     * Remove <tt>NetworkConfigurationChangeListener</tt>.
     * @param listener the listener.
     */
    public void removeNetworkConfigurationChangeListener(
        NetworkConfigurationChangeListener listener);

    /**
     * Creates and returns an ICE agent that a protocol could use for the
     * negotiation of media transport addresses. One ICE agent should only be
     * used for a single session negotiation.
     *
     * @return the newly created ICE Agent.
     */
    public Agent createIceAgent();

    /**
     * Tries to discover a TURN or a STUN server for the specified
     * <tt>domainName</tt>. The method would first try to discover a TURN
     * server and then fall back to STUN only. In both cases we would only care
     * about a UDP transport.
     *
     * @param domainName the domain name that we are trying to discover a
     * TURN server for.
     * @param userName the name of the user we'd like to use when connecting to
     * a TURN server (we won't be using credentials in case we only have a STUN
     * server).
     * @param password the password that we'd like to try when connecting to
     * a TURN server (we won't be using credentials in case we only have a STUN
     * server).
     *
     * @return A {@link StunCandidateHarvester} corresponding to the TURN or
     * STUN server we discovered or <tt>null</tt> if there were no such records
     * for the specified <tt>domainName</tt>
     */
    public StunCandidateHarvester discoverStunServer(String domainName,
                                                     byte[] userName,
                                                     byte[] password);

    /**
     * Creates an <tt>IceMediaStrean</tt> and adds to it an RTP and and RTCP
     * component, which also implies running the currently installed
     * harvesters so that they would.
     *
     * @param rtpPort the port that we should try to bind the RTP component on
     * (the RTCP one would automatically go to rtpPort + 1)
     * @param streamName the name of the stream to create
     * @param agent the <tt>Agent</tt> that should create the stream.
     *
     *@return the newly created <tt>IceMediaStream</tt>.
     *
     * @throws IllegalArgumentException if <tt>rtpPort</tt> is not a valid port
     * number.
     * @throws IOException if an error occurs while the underlying resolver
     * is using sockets.
     * @throws BindException if we couldn't find a free port between within the
     * default number of retries.
     */
    public IceMediaStream createIceStream( int    rtpPort,
                                           String streamName,
                                           Agent  agent)
        throws IllegalArgumentException,
               IOException,
               BindException;
    /**
     * Creates an <tt>IceMediaStrean</tt> and adds to it one or two
     * components, which also implies running the currently installed
     * harvesters.
     *
     * @param portBase the port that we should try to bind first component on
     * (the second one would automatically go to portBase + 1)
     * @param streamName the name of the stream to create
     * @param agent the <tt>Agent</tt> that should create the stream.
     *
     * @return the newly created <tt>IceMediaStream</tt>.
     *
     * @throws IllegalArgumentException if <tt>portBase</tt> is not a valid port
     * number. If <tt>numComponents</tt> is neither 1 nor 2.
     * @throws IOException if an error occurs while the underlying resolver
     * is using sockets.
     * @throws BindException if we couldn't find a free port between within the
     * default number of retries.
     *
     */
    public IceMediaStream createIceStream( int    numComponents,
                                           int    portBase,
                                           String streamName,
                                           Agent  agent)
        throws IllegalArgumentException,
               IOException,
               BindException;
}