~noskcaj/ubuntu/trusty/ekiga/ftbfs

« back to all changes in this revision

Viewing changes to src/clients/stun.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2006-01-28 18:49:20 UTC
  • Revision ID: james.westby@ubuntu.com-20060128184920-v525ihmiv7id40xs
Tags: upstream-1.99.0
ImportĀ upstreamĀ versionĀ 1.99.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* GnomeMeeting -- A Video-Conferencing application
 
3
 * Copyright (C) 2000-2006 Damien Sandras
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 *
 
19
 *
 
20
 * GnomeMeting is licensed under the GPL license and as a special exception,
 
21
 * you have permission to link or otherwise combine this program with the
 
22
 * programs OpenH323 and Pwlib, and distribute the combination, without
 
23
 * applying the requirements of the GNU GPL to the OpenH323 program, as long
 
24
 * as you do follow the requirements of the GNU GPL for all the rest of the
 
25
 * software thus combined.
 
26
 */
 
27
 
 
28
 
 
29
/*
 
30
 *                         stunclient.cpp  -  description
 
31
 *                         ------------------------------
 
32
 *   begin                : Thu Sep 30 2004
 
33
 *   copyright            : (C) 2000-2006 by Damien Sandras
 
34
 *   description          : Multithreaded class for the stun client.
 
35
 *
 
36
 */
 
37
 
 
38
 
 
39
#include "../../config.h" 
 
40
 
 
41
#include "stun.h"
 
42
#include "ekiga.h"
 
43
#include "manager.h"
 
44
#include "history.h"
 
45
#include "misc.h"
 
46
 
 
47
#include "gmconf.h"
 
48
#include "gmdialog.h"
 
49
 
 
50
#include <ptclib/pstun.h>
 
51
 
 
52
 
 
53
/* Declarations */
 
54
 
 
55
/* GUI Functions */
 
56
/* DESCRIPTION  :  /
 
57
 * BEHAVIOR     :  Create a dialog that presents the result of the STUN test.
 
58
 *                 If the NAT type permits it, ask to the user if he wants
 
59
 *                 to enable STUN support or not.
 
60
 * PRE          :  /
 
61
 */
 
62
static GtkWidget *
 
63
gm_sw_stun_result_window_new (GtkWidget *parent,
 
64
                              int nat_type);
 
65
 
 
66
 
 
67
/* Callbacks */
 
68
 
 
69
/* DESCRIPTION  :  This callback is called when the user validates an answer
 
70
 *                 to the stun dialog.
 
71
 * BEHAVIOR     :  Destroy the dialog and set/unset the STUN server.
 
72
 * PRE          :  /
 
73
 */
 
74
static void stun_dialog_response_cb (GtkDialog *dialog, 
 
75
                                     gint response,
 
76
                                     gpointer data);
 
77
 
 
78
 
 
79
/* Implementation */
 
80
static void 
 
81
stun_dialog_response_cb (GtkDialog *dialog, 
 
82
                         gint response,
 
83
                         gpointer data)
 
84
{
 
85
  GMManager *ep = NULL;
 
86
 
 
87
  GtkWidget *history_window = NULL;
 
88
 
 
89
  
 
90
  ep = GnomeMeeting::Process ()->GetManager ();
 
91
  history_window = GnomeMeeting::Process ()->GetHistoryWindow ();
 
92
  
 
93
  switch (response) {
 
94
 
 
95
  case GTK_RESPONSE_YES:
 
96
 
 
97
    gm_conf_set_string (NAT_KEY "stun_server", "stun.ekiga.net");
 
98
    gm_conf_set_int (NAT_KEY "method", 1);
 
99
 
 
100
    gm_history_window_insert (history_window, 
 
101
                              _("STUN server set to %s"), 
 
102
                              "stun.ekiga.net");
 
103
 
 
104
    break;
 
105
 
 
106
  case GTK_RESPONSE_NO:
 
107
 
 
108
    ((OpalManager *) ep)->SetSTUNServer (PString ());
 
109
 
 
110
    gm_history_window_insert (history_window, _("Removed STUN server"));
 
111
 
 
112
    break;
 
113
  }
 
114
  
 
115
  gtk_widget_destroy (GTK_WIDGET (dialog));
 
116
}
 
117
 
 
118
 
 
119
static GtkWidget *
 
120
gm_sw_stun_result_window_new (GtkWidget *parent,
 
121
                              int nat_type_index)
 
122
{
 
123
  GtkWidget *dialog = NULL;
 
124
  GtkWidget *dialog_label = NULL;
 
125
 
 
126
  gchar *prefered_method = NULL;
 
127
  gchar *primary_text = NULL;
 
128
  gchar *dialog_text = NULL;
 
129
 
 
130
  gboolean stun_dialog = TRUE;
 
131
 
 
132
  PString nat_type = GMStunClient::GetNatName (nat_type_index);
 
133
  
 
134
  switch (nat_type_index)
 
135
    {
 
136
    case 0:
 
137
    case 7:
 
138
    case 8:
 
139
      prefered_method = g_strdup_printf (_("STUN test result: %s.\n\nEkiga could not detect the type of NAT you are using. The most appropriate method, if your router does not natively support SIP or H.323, is probably to forward the required ports to your internal machine and use IP translation if you are behind a NAT router. Please also make sure you are not running a local firewall."), (const char *) nat_type);
 
140
      stun_dialog = FALSE;
 
141
      break;
 
142
 
 
143
    case 1:
 
144
    case 6:
 
145
      prefered_method = g_strdup_printf (_("STUN test result: %s.\n\nYour system does not need any specific configuration as long as you do not have a local firewall blocking the ports required by Ekiga."), (const char *) nat_type);
 
146
      stun_dialog = FALSE;
 
147
      break;
 
148
 
 
149
    case 5:
 
150
      prefered_method = g_strdup_printf (_("Ekiga detected Symmetric NAT. The most appropriate method, if your router does not natively support SIP or H.323, is to forward the required ports to your internal machine in order to change your Symmetric NAT into Cone NAT. Running this test again after the port forwarding has been done should report Cone NAT and allow Ekiga to be used with STUN support enabled. If it does not report Cone NAT, then it means that there is a problem in your forwarding rules."));
 
151
      stun_dialog = FALSE;
 
152
      break;
 
153
 
 
154
    default:
 
155
      prefered_method = g_strdup_printf (_("STUN test result: %s.\n\nUsing a STUN server is most probably the most appropriate method if your router does not natively support SIP or H.323.\n\nEnable STUN Support?"), (const char *) nat_type);
 
156
      stun_dialog = TRUE;
 
157
      break;
 
158
    }
 
159
 
 
160
 
 
161
  if (stun_dialog) {
 
162
 
 
163
    dialog = 
 
164
      gtk_dialog_new_with_buttons (_("NAT Detection Finished"),
 
165
                                   GTK_WINDOW (parent),
 
166
                                   GTK_DIALOG_MODAL,
 
167
                                   GTK_STOCK_NO,
 
168
                                   GTK_RESPONSE_NO,
 
169
                                   GTK_STOCK_YES,
 
170
                                   GTK_RESPONSE_YES,
 
171
                                   NULL);
 
172
    gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
 
173
  }
 
174
  else {
 
175
 
 
176
    dialog = 
 
177
      gtk_dialog_new_with_buttons (_("NAT Detection Finished"),
 
178
                                   GTK_WINDOW (parent),
 
179
                                   GTK_DIALOG_MODAL,
 
180
                                   GTK_STOCK_OK,
 
181
                                   GTK_RESPONSE_ACCEPT,
 
182
                                   NULL);
 
183
    gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
 
184
  }
 
185
 
 
186
  primary_text =
 
187
    g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>",
 
188
                     _("The detection of your NAT type is finished"));
 
189
 
 
190
  dialog_text =
 
191
    g_strdup_printf ("%s\n\n%s", primary_text, prefered_method);
 
192
 
 
193
  gtk_window_set_title (GTK_WINDOW (dialog), "");
 
194
  dialog_label = gtk_label_new (NULL);
 
195
  gtk_label_set_markup (GTK_LABEL (dialog_label),
 
196
                        dialog_text);
 
197
  gtk_label_set_line_wrap (GTK_LABEL (dialog_label), TRUE);
 
198
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
 
199
                     dialog_label);
 
200
 
 
201
  g_signal_connect (GTK_WINDOW (dialog), "response",
 
202
                    G_CALLBACK (stun_dialog_response_cb), NULL);
 
203
 
 
204
  g_free (prefered_method);
 
205
  g_free (primary_text);
 
206
  g_free (dialog_text);
 
207
 
 
208
  return dialog;
 
209
}
 
210
 
 
211
 
 
212
/* The class */
 
213
GMStunClient::GMStunClient (BOOL d,
 
214
                            BOOL c,
 
215
                            BOOL w,
 
216
                            GtkWidget *parent_window,
 
217
                            GMManager & endpoint)
 
218
  :PThread (1000, NoAutoDeleteThread), 
 
219
  ep (endpoint)
 
220
{
 
221
  gchar *conf_string = NULL;
 
222
  int nat_method = 0;
 
223
  
 
224
  gnomemeeting_threads_enter ();
 
225
  nat_method = gm_conf_get_int (NAT_KEY "method");
 
226
  conf_string = gm_conf_get_string (NAT_KEY "stun_server");
 
227
  stun_host = conf_string;
 
228
  gnomemeeting_threads_leave ();
 
229
  
 
230
  display_progress = d;
 
231
  display_config_dialog = c;
 
232
  wait = w;
 
233
 
 
234
  parent = parent_window;
 
235
  
 
236
  this->Resume ();
 
237
  if (wait)
 
238
    sync.Wait ();
 
239
  
 
240
  g_free (conf_string);
 
241
}
 
242
 
 
243
 
 
244
GMStunClient::~GMStunClient ()
 
245
{
 
246
  /* Nothing to do here */
 
247
  PWaitAndSignal m(quit_mutex);
 
248
}
 
249
 
 
250
 
 
251
PString GMStunClient::GetNatName (int i)
 
252
{
 
253
  char *name [] = 
 
254
    { 
 
255
      N_("Unknown NAT"), 
 
256
      N_("Open NAT"),
 
257
      N_("Cone NAT"), 
 
258
      N_("Restricted NAT"), 
 
259
      N_("Port Restricted NAT"),
 
260
      N_("Symmetric NAT"), 
 
261
      N_("Symmetric Firewall"), 
 
262
      N_("Blocked"),
 
263
      N_("Partially Blocked"),
 
264
      NULL,
 
265
    };
 
266
 
 
267
  return PString (gettext (name [i]));
 
268
}
 
269
 
 
270
 
 
271
void GMStunClient::Main ()
 
272
{
 
273
  GtkWidget *history_window = NULL;
 
274
  GtkWidget *main_window = NULL;
 
275
 
 
276
  PSTUNClient *stun = NULL;
 
277
 
 
278
  int nat_type_index = 0;
 
279
 
 
280
  main_window = GnomeMeeting::Process ()->GetMainWindow ();
 
281
  history_window = GnomeMeeting::Process ()->GetHistoryWindow ();
 
282
 
 
283
  GtkWidget *progress_dialog = NULL;
 
284
  GtkWidget *dialog = NULL;
 
285
 
 
286
 
 
287
  PWaitAndSignal m(quit_mutex);
 
288
 
 
289
  /* Async remove the current stun server setting */
 
290
  if (stun_host.IsEmpty ()) {
 
291
 
 
292
    if (wait)
 
293
      sync.Signal ();
 
294
 
 
295
    ((OpalManager *) &ep)->SetSTUNServer (PString ());
 
296
    
 
297
    return;
 
298
  }
 
299
 
 
300
  /* Display a progress dialog */
 
301
  if (display_progress) {
 
302
 
 
303
    gnomemeeting_threads_enter ();
 
304
    progress_dialog = 
 
305
      gnomemeeting_progress_dialog (GTK_WINDOW (parent),
 
306
                                    _("Detection in progress"), 
 
307
                                    _("Please wait while your type of NAT is being detected."));
 
308
    gnomemeeting_threads_dialog_show_all (progress_dialog);
 
309
    gnomemeeting_threads_leave ();
 
310
  }
 
311
 
 
312
  /* Set the STUN server for the endpoint */
 
313
  ((OpalManager *) &ep)->SetSTUNServer (stun_host);
 
314
 
 
315
  stun = ep.GetSTUN ();
 
316
 
 
317
  if (stun) {
 
318
 
 
319
    nat_type_index = stun->GetNatType ();
 
320
    nat_type = GetNatName (nat_type_index);
 
321
    if (wait)
 
322
      sync.Signal ();
 
323
 
 
324
    if (!display_config_dialog) {
 
325
 
 
326
      gnomemeeting_threads_enter ();
 
327
      gm_history_window_insert (history_window, _("Set STUN server to %s (%s)"), (const char *) stun_host, (const char *) nat_type);
 
328
      gnomemeeting_threads_leave ();
 
329
    }
 
330
  }
 
331
 
 
332
  /* Show the config dialog */
 
333
  gnomemeeting_threads_enter ();
 
334
  if (display_config_dialog) {
 
335
 
 
336
    dialog = gm_sw_stun_result_window_new (parent, nat_type_index);
 
337
    gnomemeeting_threads_dialog_show_all (dialog);
 
338
  }
 
339
  gnomemeeting_threads_leave ();
 
340
 
 
341
 
 
342
  /* Delete the progress if any */
 
343
  gnomemeeting_threads_enter ();
 
344
  if (display_progress) 
 
345
    gnomemeeting_threads_widget_destroy (progress_dialog);
 
346
  gnomemeeting_threads_leave ();
 
347
}