1 /*
2 Copyright (c) 2007, Adobe Systems, Incorporated
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9 * Redistributions of source code must retain the above copyright
10   notice, this list of conditions and the following disclaimer.
11 
12 * Redistributions in binary form must reproduce the above copyright
13   notice, this list of conditions and the following disclaimer in the
14   documentation and/or other materials provided with the distribution.
15 
16 * Neither the name of Adobe Systems, Network Resonance nor the names of its
17   contributors may be used to endorse or promote products derived from
18   this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 
34 
35 #ifndef _stun_client_ctx_h
36 #define _stun_client_ctx_h
37 
38 /* forward declaration */
39 typedef struct nr_stun_client_ctx_ nr_stun_client_ctx;
40 
41 #include "stun.h"
42 
43 /* Checklist for adding new STUN transaction types
44 
45    1. Add new method type in stun.h (NR_METHOD_*)
46    2. Add new MSGs in stun.h (NR_STUN_MSG_*)
47    3. Add new messages to stun_util.c:nr_stun_msg_type
48    4. Add new request type to stun_build.h
49    4. Add new message builder to stun_build.c
50    5. Add new response type to stun_client_ctx.h
51    6. Add new arm to stun_client_ctx.c:nr_stun_client_send_request
52    7. Add new arms to nr_stun_client_process_response
53    8. Add new arms to stun_hint.c:nr_is_stun_message
54 */
55 
56 
57 
58 
59 typedef union nr_stun_client_params_ {
60 
61     nr_stun_client_stun_binding_request_params               stun_binding_request;
62     nr_stun_client_stun_keepalive_params                     stun_keepalive;
63 #ifdef USE_STUND_0_96
64     nr_stun_client_stun_binding_request_stund_0_96_params    stun_binding_request_stund_0_96;
65 #endif /* USE_STUND_0_96 */
66 
67 #ifdef USE_ICE
68     nr_stun_client_ice_binding_request_params                ice_binding_request;
69 #endif /* USE_ICE */
70 
71 #ifdef USE_TURN
72     nr_stun_client_allocate_request_params                   allocate_request;
73     nr_stun_client_refresh_request_params                    refresh_request;
74     nr_stun_client_permission_request_params                 permission_request;
75     nr_stun_client_send_indication_params                    send_indication;
76 #endif /* USE_TURN */
77 
78 } nr_stun_client_params;
79 
80 typedef struct nr_stun_client_stun_binding_response_results_ {
81     nr_transport_addr mapped_addr;
82 } nr_stun_client_stun_binding_response_results;
83 
84 typedef struct nr_stun_client_stun_binding_response_stund_0_96_results_ {
85     nr_transport_addr mapped_addr;
86 } nr_stun_client_stun_binding_response_stund_0_96_results;
87 
88 #ifdef USE_ICE
89 typedef struct nr_stun_client_ice_use_candidate_results_ {
90 #ifdef WIN32  // silly VC++ gives error if no members
91     int dummy;
92 #endif
93 } nr_stun_client_ice_use_candidate_results;
94 
95 typedef struct nr_stun_client_ice_binding_response_results_ {
96     nr_transport_addr mapped_addr;
97 } nr_stun_client_ice_binding_response_results;
98 #endif /* USE_ICE */
99 
100 #ifdef USE_TURN
101 typedef struct nr_stun_client_allocate_response_results_ {
102     nr_transport_addr relay_addr;
103     nr_transport_addr mapped_addr;
104     UINT4 lifetime_secs;
105 } nr_stun_client_allocate_response_results;
106 
107 typedef struct nr_stun_client_refresh_response_results_ {
108     UINT4 lifetime_secs;
109 } nr_stun_client_refresh_response_results;
110 
111 typedef struct nr_stun_client_permission_response_results_ {
112     UINT4 lifetime_secs;
113 } nr_stun_client_permission_response_results;
114 
115 #endif /* USE_TURN */
116 
117 typedef union nr_stun_client_results_ {
118     nr_stun_client_stun_binding_response_results              stun_binding_response;
119     nr_stun_client_stun_binding_response_stund_0_96_results   stun_binding_response_stund_0_96;
120 
121 #ifdef USE_ICE
122     nr_stun_client_ice_use_candidate_results                  ice_use_candidate;
123     nr_stun_client_ice_binding_response_results               ice_binding_response;
124 #endif /* USE_ICE */
125 
126 #ifdef USE_TURN
127     nr_stun_client_allocate_response_results                   allocate_response;
128     nr_stun_client_refresh_response_results                    refresh_response;
129 #endif /* USE_TURN */
130 } nr_stun_client_results;
131 
132 struct nr_stun_client_ctx_ {
133   int state;
134 #define NR_STUN_CLIENT_STATE_INITTED         0
135 #define NR_STUN_CLIENT_STATE_RUNNING         1
136 #define NR_STUN_CLIENT_STATE_DONE            2
137 #define NR_STUN_CLIENT_STATE_FAILED          3
138 #define NR_STUN_CLIENT_STATE_TIMED_OUT       4
139 #define NR_STUN_CLIENT_STATE_CANCELLED       5
140 #define NR_STUN_CLIENT_STATE_WAITING         6
141 
142   int mode;
143 #define NR_STUN_CLIENT_MODE_BINDING_REQUEST_SHORT_TERM_AUTH   1
144 #define NR_STUN_CLIENT_MODE_BINDING_REQUEST_LONG_TERM_AUTH    2
145 #define NR_STUN_CLIENT_MODE_BINDING_REQUEST_NO_AUTH           3
146 #define NR_STUN_CLIENT_MODE_KEEPALIVE                         4
147 #define NR_STUN_CLIENT_MODE_BINDING_REQUEST_STUND_0_96        5
148 #ifdef USE_ICE
149 #define NR_ICE_CLIENT_MODE_USE_CANDIDATE                  10
150 #define NR_ICE_CLIENT_MODE_BINDING_REQUEST                11
151 #endif /* USE_ICE */
152 #ifdef USE_TURN
153 #define NR_TURN_CLIENT_MODE_ALLOCATE_REQUEST              20
154 #define NR_TURN_CLIENT_MODE_REFRESH_REQUEST               21
155 #define NR_TURN_CLIENT_MODE_SEND_INDICATION               22
156 #define NR_TURN_CLIENT_MODE_DATA_INDICATION               24
157 #define NR_TURN_CLIENT_MODE_PERMISSION_REQUEST            25
158 #endif /* USE_TURN */
159 
160   char *label;
161   nr_transport_addr my_addr;
162   nr_transport_addr peer_addr;
163   nr_socket *sock;
164   nr_stun_client_auth_params auth_params;
165   nr_stun_client_params params;
166   nr_stun_client_results results;
167   char *nonce;
168   char *realm;
169   void *timer_handle;
170   int request_ct;
171   UINT4 rto_ms;    /* retransmission time out */
172   double retransmission_backoff_factor;
173   UINT4 maximum_transmits;
174   UINT4 maximum_transmits_timeout_ms;
175   UINT4 mapped_addr_check_mask;  /* What checks to run on mapped addresses */
176   int timeout_ms;
177   struct timeval timer_set;
178   int retry_ct;
179   NR_async_cb finished_cb;
180   void *cb_arg;
181   nr_stun_message *request;
182   nr_stun_message *response;
183   UINT2 error_code;
184 };
185 
186 int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *peer, UINT4 RTO, nr_stun_client_ctx **ctxp);
187 int nr_stun_client_start(nr_stun_client_ctx *ctx, int mode, NR_async_cb finished_cb, void *cb_arg);
188 int nr_stun_client_restart(nr_stun_client_ctx *ctx);
189 int nr_stun_client_force_retransmit(nr_stun_client_ctx *ctx);
190 int nr_stun_client_reset(nr_stun_client_ctx *ctx);
191 int nr_stun_client_ctx_destroy(nr_stun_client_ctx **ctxp);
192 int nr_stun_transport_addr_check(nr_transport_addr* addr, UINT4 mask);
193 int nr_stun_client_process_response(nr_stun_client_ctx *ctx, UCHAR *msg, int len, nr_transport_addr *peer_addr);
194 int nr_stun_client_cancel(nr_stun_client_ctx *ctx);
195 int nr_stun_client_wait(nr_stun_client_ctx *ctx);
196 int nr_stun_client_failed(nr_stun_client_ctx *ctx);
197 
198 #endif
199 
200