~ubuntu-branches/ubuntu/saucy/openvpn/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/jjo-ipv6-support.patch/multi.c

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2013-05-24 17:42:45 UTC
  • mfrom: (1.1.19) (10.2.22 sid)
  • Revision ID: package-import@ubuntu.com-20130524174245-g9y6wlforycufqy5
Tags: 2.3.1-2ubuntu1
* Merge from Debian unstable. Remaining changes:
  - debian/openvpn.init.d:
    + Do not use start-stop-daemon and </dev/null to avoid blocking boot.
    + Show per-VPN result messages.
    + Add "--script-security 2" by default for backwards compatabliity.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  OpenVPN -- An application to securely tunnel IP networks
3
 
 *             over a single TCP/UDP port, with support for SSL/TLS-based
4
 
 *             session authentication and key exchange,
5
 
 *             packet encryption, packet authentication, and
6
 
 *             packet compression.
7
 
 *
8
 
 *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
9
 
 *
10
 
 *  This program is free software; you can redistribute it and/or modify
11
 
 *  it under the terms of the GNU General Public License version 2
12
 
 *  as published by the Free Software Foundation.
13
 
 *
14
 
 *  This program is distributed in the hope that it will be useful,
15
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
 *  GNU General Public License for more details.
18
 
 *
19
 
 *  You should have received a copy of the GNU General Public License
20
 
 *  along with this program (see the file COPYING included with this
21
 
 *  distribution); if not, write to the Free Software Foundation, Inc.,
22
 
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 
 */
24
 
 
25
 
#include "syshead.h"
26
 
 
27
 
#if P2MP_SERVER
28
 
 
29
 
#include "multi.h"
30
 
#include "push.h"
31
 
#include "misc.h"
32
 
#include "otime.h"
33
 
#include "gremlin.h"
34
 
 
35
 
#include "memdbg.h"
36
 
 
37
 
#include "forward-inline.h"
38
 
#include "pf-inline.h"
39
 
 
40
 
/*#define MULTI_DEBUG_EVENT_LOOP*/
41
 
 
42
 
#ifdef MULTI_DEBUG_EVENT_LOOP
43
 
static const char *
44
 
id (struct multi_instance *mi)
45
 
{
46
 
  if (mi)
47
 
    return tls_common_name (mi->context.c2.tls_multi, false);
48
 
  else
49
 
    return "NULL";
50
 
}
51
 
#endif
52
 
 
53
 
#ifdef MANAGEMENT_DEF_AUTH
54
 
static void
55
 
set_cc_config (struct multi_instance *mi, struct buffer_list *cc_config)
56
 
{
57
 
  if (mi->cc_config)
58
 
    buffer_list_free (mi->cc_config);
59
 
  mi->cc_config = cc_config;
60
 
}
61
 
#endif
62
 
 
63
 
static bool
64
 
learn_address_script (const struct multi_context *m,
65
 
                      const struct multi_instance *mi,
66
 
                      const char *op,
67
 
                      const struct mroute_addr *addr)
68
 
{
69
 
  struct gc_arena gc = gc_new ();
70
 
  struct env_set *es;
71
 
  bool ret = true;
72
 
  struct plugin_list *plugins;
73
 
 
74
 
  /* get environmental variable source */
75
 
  if (mi && mi->context.c2.es)
76
 
    es = mi->context.c2.es;
77
 
  else
78
 
    es = env_set_create (&gc);
79
 
 
80
 
  /* get plugin source */
81
 
  if (mi)
82
 
    plugins = mi->context.plugins;
83
 
  else
84
 
    plugins = m->top.plugins;
85
 
 
86
 
  if (plugin_defined (plugins, OPENVPN_PLUGIN_LEARN_ADDRESS))
87
 
    {
88
 
      struct argv argv = argv_new ();
89
 
      argv_printf (&argv, "%s %s",
90
 
                   op,
91
 
                   mroute_addr_print (addr, &gc));
92
 
      if (mi)
93
 
        argv_printf_cat (&argv, "%s", tls_common_name (mi->context.c2.tls_multi, false));
94
 
      if (plugin_call (plugins, OPENVPN_PLUGIN_LEARN_ADDRESS, &argv, NULL, es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
95
 
        {
96
 
          msg (M_WARN, "WARNING: learn-address plugin call failed");
97
 
          ret = false;
98
 
        }
99
 
      argv_reset (&argv);
100
 
    }
101
 
 
102
 
  if (m->top.options.learn_address_script)
103
 
    {
104
 
      struct argv argv = argv_new ();
105
 
      setenv_str (es, "script_type", "learn-address");
106
 
      argv_printf (&argv, "%sc %s %s",
107
 
                   m->top.options.learn_address_script,
108
 
                   op,
109
 
                   mroute_addr_print (addr, &gc));
110
 
      if (mi)
111
 
        argv_printf_cat (&argv, "%s", tls_common_name (mi->context.c2.tls_multi, false));
112
 
      if (!openvpn_run_script (&argv, es, 0, "--learn-address"))
113
 
        ret = false;
114
 
      argv_reset (&argv);
115
 
    }
116
 
 
117
 
  gc_free (&gc);
118
 
  return ret;
119
 
}
120
 
 
121
 
void
122
 
multi_ifconfig_pool_persist (struct multi_context *m, bool force)
123
 
{
124
 
 /* write pool data to file */
125
 
  if (m->ifconfig_pool
126
 
      && m->top.c1.ifconfig_pool_persist
127
 
      && (force || ifconfig_pool_write_trigger (m->top.c1.ifconfig_pool_persist)))
128
 
    {
129
 
      ifconfig_pool_write (m->top.c1.ifconfig_pool_persist, m->ifconfig_pool);
130
 
    }
131
 
}
132
 
 
133
 
static void
134
 
multi_reap_range (const struct multi_context *m,
135
 
                  int start_bucket,
136
 
                  int end_bucket)
137
 
{
138
 
  struct gc_arena gc = gc_new ();
139
 
  struct hash_iterator hi;
140
 
  struct hash_element *he;
141
 
 
142
 
  if (start_bucket < 0)
143
 
    {
144
 
      start_bucket = 0;
145
 
      end_bucket = hash_n_buckets (m->vhash);
146
 
    }
147
 
 
148
 
  dmsg (D_MULTI_DEBUG, "MULTI: REAP range %d -> %d", start_bucket, end_bucket);
149
 
  hash_iterator_init_range (m->vhash, &hi, start_bucket, end_bucket);
150
 
  while ((he = hash_iterator_next (&hi)) != NULL)
151
 
    {
152
 
      struct multi_route *r = (struct multi_route *) he->value;
153
 
      if (!multi_route_defined (m, r))
154
 
        {
155
 
          dmsg (D_MULTI_DEBUG, "MULTI: REAP DEL %s",
156
 
               mroute_addr_print (&r->addr, &gc));
157
 
          learn_address_script (m, NULL, "delete", &r->addr);
158
 
          multi_route_del (r);
159
 
          hash_iterator_delete_element (&hi);
160
 
        }
161
 
    }
162
 
  hash_iterator_free (&hi);
163
 
  gc_free (&gc);
164
 
}
165
 
 
166
 
static void
167
 
multi_reap_all (const struct multi_context *m)
168
 
{
169
 
  multi_reap_range (m, -1, 0);
170
 
}
171
 
 
172
 
static struct multi_reap *
173
 
multi_reap_new (int buckets_per_pass)
174
 
{
175
 
  struct multi_reap *mr;
176
 
  ALLOC_OBJ (mr, struct multi_reap);
177
 
  mr->bucket_base = 0;
178
 
  mr->buckets_per_pass = buckets_per_pass;
179
 
  mr->last_call = now;
180
 
  return mr;
181
 
}
182
 
 
183
 
void
184
 
multi_reap_process_dowork (const struct multi_context *m)
185
 
{
186
 
  struct multi_reap *mr = m->reaper;
187
 
  if (mr->bucket_base >= hash_n_buckets (m->vhash))
188
 
    mr->bucket_base = 0;
189
 
  multi_reap_range (m, mr->bucket_base, mr->bucket_base + mr->buckets_per_pass); 
190
 
  mr->bucket_base += mr->buckets_per_pass;
191
 
  mr->last_call = now;
192
 
}
193
 
 
194
 
static void
195
 
multi_reap_free (struct multi_reap *mr)
196
 
{
197
 
  free (mr);
198
 
}
199
 
 
200
 
/*
201
 
 * How many buckets in vhash to reap per pass.
202
 
 */
203
 
static int
204
 
reap_buckets_per_pass (int n_buckets)
205
 
{
206
 
  return constrain_int (n_buckets / REAP_DIVISOR, REAP_MIN, REAP_MAX);
207
 
}
208
 
 
209
 
#ifdef MANAGEMENT_DEF_AUTH
210
 
 
211
 
static uint32_t
212
 
cid_hash_function (const void *key, uint32_t iv)
213
 
{
214
 
  const unsigned long *k = (const unsigned long *)key;
215
 
  return (uint32_t) *k;
216
 
}
217
 
 
218
 
static bool
219
 
cid_compare_function (const void *key1, const void *key2)
220
 
{
221
 
  const unsigned long *k1 = (const unsigned long *)key1;
222
 
  const unsigned long *k2 = (const unsigned long *)key2;
223
 
  return *k1 == *k2;
224
 
}
225
 
 
226
 
#endif
227
 
 
228
 
/*
229
 
 * Main initialization function, init multi_context object.
230
 
 */
231
 
void
232
 
multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int thread_mode)
233
 
{
234
 
  int dev = DEV_TYPE_UNDEF;
235
 
 
236
 
  msg (D_MULTI_LOW, "MULTI: multi_init called, r=%d v=%d",
237
 
       t->options.real_hash_size,
238
 
       t->options.virtual_hash_size);
239
 
 
240
 
  /*
241
 
   * Get tun/tap/null device type
242
 
   */
243
 
  dev = dev_type_enum (t->options.dev, t->options.dev_type);
244
 
 
245
 
  /*
246
 
   * Init our multi_context object.
247
 
   */
248
 
  CLEAR (*m);
249
 
  
250
 
  m->thread_mode = thread_mode;
251
 
 
252
 
  /*
253
 
   * Real address hash table (source port number is
254
 
   * considered to be part of the address).  Used
255
 
   * to determine which client sent an incoming packet
256
 
   * which is seen on the TCP/UDP socket.
257
 
   */
258
 
  m->hash = hash_init (t->options.real_hash_size,
259
 
                       get_random (),
260
 
                       mroute_addr_hash_function,
261
 
                       mroute_addr_compare_function);
262
 
 
263
 
  /*
264
 
   * Virtual address hash table.  Used to determine
265
 
   * which client to route a packet to. 
266
 
   */
267
 
  m->vhash = hash_init (t->options.virtual_hash_size,
268
 
                        get_random (),
269
 
                        mroute_addr_hash_function,
270
 
                        mroute_addr_compare_function);
271
 
 
272
 
  /*
273
 
   * This hash table is a clone of m->hash but with a
274
 
   * bucket size of one so that it can be used
275
 
   * for fast iteration through the list.
276
 
   */
277
 
  m->iter = hash_init (1,
278
 
                       get_random (),
279
 
                       mroute_addr_hash_function,
280
 
                       mroute_addr_compare_function);
281
 
 
282
 
#ifdef MANAGEMENT_DEF_AUTH
283
 
  m->cid_hash = hash_init (t->options.real_hash_size,
284
 
                           0,
285
 
                           cid_hash_function,
286
 
                           cid_compare_function);
287
 
#endif
288
 
 
289
 
  /*
290
 
   * This is our scheduler, for time-based wakeup
291
 
   * events.
292
 
   */
293
 
  m->schedule = schedule_init ();
294
 
 
295
 
  /*
296
 
   * Limit frequency of incoming connections to control
297
 
   * DoS.
298
 
   */
299
 
  m->new_connection_limiter = frequency_limit_init (t->options.cf_max,
300
 
                                                    t->options.cf_per);
301
 
 
302
 
  /*
303
 
   * Allocate broadcast/multicast buffer list
304
 
   */
305
 
  m->mbuf = mbuf_init (t->options.n_bcast_buf);
306
 
 
307
 
  /*
308
 
   * Different status file format options are available
309
 
   */
310
 
  m->status_file_version = t->options.status_file_version;
311
 
 
312
 
  /*
313
 
   * Possibly allocate an ifconfig pool, do it
314
 
   * differently based on whether a tun or tap style
315
 
   * tunnel.
316
 
   */
317
 
  if (t->options.ifconfig_pool_defined)
318
 
    {
319
 
      if (dev == DEV_TYPE_TAP)
320
 
        {
321
 
          m->ifconfig_pool = ifconfig_pool_init (IFCONFIG_POOL_INDIV,
322
 
                                                 t->options.ifconfig_pool_start,
323
 
                                                 t->options.ifconfig_pool_end,
324
 
                                                 t->options.duplicate_cn);
325
 
        }
326
 
      else if (dev == DEV_TYPE_TUN)
327
 
        {
328
 
          m->ifconfig_pool = ifconfig_pool_init (
329
 
            (t->options.topology == TOP_NET30) ? IFCONFIG_POOL_30NET : IFCONFIG_POOL_INDIV,
330
 
            t->options.ifconfig_pool_start,
331
 
            t->options.ifconfig_pool_end,
332
 
            t->options.duplicate_cn);
333
 
        }
334
 
      else
335
 
        {
336
 
          ASSERT (0);
337
 
        }
338
 
 
339
 
      /* reload pool data from file */
340
 
      if (t->c1.ifconfig_pool_persist)
341
 
        ifconfig_pool_read (t->c1.ifconfig_pool_persist, m->ifconfig_pool);
342
 
    }
343
 
 
344
 
  /*
345
 
   * Help us keep track of routing table.
346
 
   */
347
 
  m->route_helper = mroute_helper_init (MULTI_CACHE_ROUTE_TTL);
348
 
 
349
 
  /*
350
 
   * Initialize route and instance reaper.
351
 
   */
352
 
  m->reaper = multi_reap_new (reap_buckets_per_pass (t->options.virtual_hash_size));
353
 
 
354
 
  /*
355
 
   * Get local ifconfig address
356
 
   */
357
 
  CLEAR (m->local);
358
 
  ASSERT (t->c1.tuntap);
359
 
  mroute_extract_in_addr_t (&m->local, t->c1.tuntap->local);
360
 
 
361
 
  /*
362
 
   * Per-client limits
363
 
   */
364
 
  m->max_clients = t->options.max_clients;
365
 
 
366
 
  /*
367
 
   * Initialize multi-socket TCP I/O wait object
368
 
   */
369
 
  if (tcp_mode)
370
 
    m->mtcp = multi_tcp_init (t->options.max_clients, &m->max_clients);
371
 
  m->tcp_queue_limit = t->options.tcp_queue_limit;
372
 
  
373
 
  /*
374
 
   * Allow client <-> client communication, without going through
375
 
   * tun/tap interface and network stack?
376
 
   */
377
 
  m->enable_c2c = t->options.enable_c2c;
378
 
}
379
 
 
380
 
const char *
381
 
multi_instance_string (const struct multi_instance *mi, bool null, struct gc_arena *gc)
382
 
{
383
 
  if (mi)
384
 
    {
385
 
      struct buffer out = alloc_buf_gc (256, gc);
386
 
      const char *cn = tls_common_name (mi->context.c2.tls_multi, true);
387
 
 
388
 
      if (cn)
389
 
        buf_printf (&out, "%s/", cn);
390
 
      buf_printf (&out, "%s", mroute_addr_print (&mi->real, gc));
391
 
      return BSTR (&out);
392
 
    }
393
 
  else if (null)
394
 
    return NULL;
395
 
  else
396
 
    return "UNDEF";
397
 
}
398
 
 
399
 
void
400
 
generate_prefix (struct multi_instance *mi)
401
 
{
402
 
  mi->msg_prefix = multi_instance_string (mi, true, &mi->gc);
403
 
  set_prefix (mi);
404
 
}
405
 
 
406
 
void
407
 
ungenerate_prefix (struct multi_instance *mi)
408
 
{
409
 
  mi->msg_prefix = NULL;
410
 
  set_prefix (mi);
411
 
}
412
 
 
413
 
static const char *
414
 
mi_prefix (const struct multi_instance *mi)
415
 
{
416
 
  if (mi && mi->msg_prefix)
417
 
    return mi->msg_prefix;
418
 
  else
419
 
    return "UNDEF_I";
420
 
}
421
 
 
422
 
/*
423
 
 * Tell the route helper about deleted iroutes so
424
 
 * that it can update its mask of currently used
425
 
 * CIDR netlengths.
426
 
 */
427
 
static void
428
 
multi_del_iroutes (struct multi_context *m,
429
 
                   struct multi_instance *mi)
430
 
{
431
 
  const struct iroute *ir;
432
 
  if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
433
 
    {
434
 
      for (ir = mi->context.options.iroutes; ir != NULL; ir = ir->next)
435
 
        mroute_helper_del_iroute (m->route_helper, ir);
436
 
    }
437
 
}
438
 
 
439
 
static void
440
 
setenv_stats (struct context *c)
441
 
{
442
 
  setenv_counter (c->c2.es, "bytes_received", c->c2.link_read_bytes);
443
 
  setenv_counter (c->c2.es, "bytes_sent", c->c2.link_write_bytes);
444
 
}
445
 
 
446
 
static void
447
 
multi_client_disconnect_setenv (struct multi_context *m,
448
 
                                struct multi_instance *mi)
449
 
{
450
 
  /* setenv client real IP address */
451
 
  setenv_trusted (mi->context.c2.es, get_link_socket_info (&mi->context));
452
 
 
453
 
  /* setenv stats */
454
 
  setenv_stats (&mi->context);
455
 
 
456
 
  /* setenv connection duration */
457
 
  {
458
 
    const unsigned int duration = (unsigned int) now - mi->created;
459
 
    setenv_unsigned (mi->context.c2.es, "time_duration", duration);
460
 
  }
461
 
}
462
 
 
463
 
static void
464
 
multi_client_disconnect_script (struct multi_context *m,
465
 
                                struct multi_instance *mi)
466
 
{
467
 
  if ((mi->context.c2.context_auth == CAS_SUCCEEDED && mi->connection_established_flag)
468
 
      || mi->context.c2.context_auth == CAS_PARTIAL)
469
 
    {
470
 
      multi_client_disconnect_setenv (m, mi);
471
 
 
472
 
      if (plugin_defined (mi->context.plugins, OPENVPN_PLUGIN_CLIENT_DISCONNECT))
473
 
        {
474
 
          if (plugin_call (mi->context.plugins, OPENVPN_PLUGIN_CLIENT_DISCONNECT, NULL, NULL, mi->context.c2.es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
475
 
            msg (M_WARN, "WARNING: client-disconnect plugin call failed");
476
 
        }
477
 
 
478
 
      if (mi->context.options.client_disconnect_script)
479
 
        {
480
 
          struct argv argv = argv_new ();
481
 
          setenv_str (mi->context.c2.es, "script_type", "client-disconnect");
482
 
          argv_printf (&argv, "%sc", mi->context.options.client_disconnect_script);
483
 
          openvpn_run_script (&argv, mi->context.c2.es, 0, "--client-disconnect");
484
 
          argv_reset (&argv);
485
 
        }
486
 
#ifdef MANAGEMENT_DEF_AUTH
487
 
      if (management)
488
 
        management_notify_client_close (management, &mi->context.c2.mda_context, mi->context.c2.es);
489
 
#endif
490
 
 
491
 
    }
492
 
}
493
 
 
494
 
void
495
 
multi_close_instance (struct multi_context *m,
496
 
                      struct multi_instance *mi,
497
 
                      bool shutdown)
498
 
{
499
 
  perf_push (PERF_MULTI_CLOSE_INSTANCE);
500
 
 
501
 
  ASSERT (!mi->halt);
502
 
  mi->halt = true;
503
 
 
504
 
  dmsg (D_MULTI_DEBUG, "MULTI: multi_close_instance called");
505
 
 
506
 
  /* adjust current client connection count */
507
 
  m->n_clients += mi->n_clients_delta;
508
 
  mi->n_clients_delta = 0;
509
 
 
510
 
  /* prevent dangling pointers */
511
 
  if (m->pending == mi)
512
 
    multi_set_pending (m, NULL);
513
 
  if (m->earliest_wakeup == mi)
514
 
    m->earliest_wakeup = NULL;
515
 
 
516
 
  if (!shutdown)
517
 
    {
518
 
      if (mi->did_real_hash)
519
 
        {
520
 
          ASSERT (hash_remove (m->hash, &mi->real));
521
 
        }
522
 
      if (mi->did_iter)
523
 
        {
524
 
          ASSERT (hash_remove (m->iter, &mi->real));
525
 
        }
526
 
#ifdef MANAGEMENT_DEF_AUTH
527
 
      if (mi->did_cid_hash)
528
 
        {
529
 
          ASSERT (hash_remove (m->cid_hash, &mi->context.c2.mda_context.cid));
530
 
        }
531
 
#endif
532
 
 
533
 
      schedule_remove_entry (m->schedule, (struct schedule_entry *) mi);
534
 
 
535
 
      ifconfig_pool_release (m->ifconfig_pool, mi->vaddr_handle, false);
536
 
      
537
 
      if (mi->did_iroutes)
538
 
        {
539
 
          multi_del_iroutes (m, mi);
540
 
          mi->did_iroutes = false;
541
 
        }
542
 
 
543
 
      if (m->mtcp)
544
 
        multi_tcp_dereference_instance (m->mtcp, mi);
545
 
 
546
 
      mbuf_dereference_instance (m->mbuf, mi);
547
 
    }
548
 
 
549
 
#ifdef MANAGEMENT_DEF_AUTH
550
 
  set_cc_config (mi, NULL);
551
 
#endif
552
 
 
553
 
  multi_client_disconnect_script (m, mi);
554
 
 
555
 
  if (mi->did_open_context)
556
 
    close_context (&mi->context, SIGTERM, CC_GC_FREE);
557
 
 
558
 
  multi_tcp_instance_specific_free (mi);
559
 
 
560
 
  ungenerate_prefix (mi);
561
 
 
562
 
  /*
563
 
   * Don't actually delete the instance memory allocation yet,
564
 
   * because virtual routes may still point to it.  Let the
565
 
   * vhash reaper deal with it.
566
 
   */
567
 
  multi_instance_dec_refcount (mi);
568
 
 
569
 
  perf_pop ();
570
 
}
571
 
 
572
 
/*
573
 
 * Called on shutdown or restart.
574
 
 */
575
 
void
576
 
multi_uninit (struct multi_context *m)
577
 
{
578
 
  if (m->thread_mode & MC_WORK_THREAD)
579
 
    {
580
 
      multi_top_free (m);
581
 
      m->thread_mode = MC_UNDEF;
582
 
    }
583
 
  else if (m->thread_mode)
584
 
    {
585
 
      if (m->hash)
586
 
        {
587
 
          struct hash_iterator hi;
588
 
          struct hash_element *he;
589
 
 
590
 
          hash_iterator_init (m->iter, &hi);
591
 
          while ((he = hash_iterator_next (&hi)))
592
 
            {
593
 
              struct multi_instance *mi = (struct multi_instance *) he->value;
594
 
              mi->did_iter = false;
595
 
              multi_close_instance (m, mi, true);
596
 
            }
597
 
          hash_iterator_free (&hi);
598
 
 
599
 
          multi_reap_all (m);
600
 
 
601
 
          hash_free (m->hash);
602
 
          hash_free (m->vhash);
603
 
          hash_free (m->iter);
604
 
#ifdef MANAGEMENT_DEF_AUTH
605
 
          hash_free (m->cid_hash);
606
 
#endif
607
 
          m->hash = NULL;
608
 
 
609
 
          schedule_free (m->schedule);
610
 
          mbuf_free (m->mbuf);
611
 
          ifconfig_pool_free (m->ifconfig_pool);
612
 
          frequency_limit_free (m->new_connection_limiter);
613
 
          multi_reap_free (m->reaper);
614
 
          mroute_helper_free (m->route_helper);
615
 
          multi_tcp_free (m->mtcp);
616
 
          m->thread_mode = MC_UNDEF;
617
 
        }
618
 
    }
619
 
}
620
 
 
621
 
/*
622
 
 * Create a client instance object for a newly connected client.
623
 
 */
624
 
struct multi_instance *
625
 
multi_create_instance (struct multi_context *m, const struct mroute_addr *real)
626
 
{
627
 
  struct gc_arena gc = gc_new ();
628
 
  struct multi_instance *mi;
629
 
 
630
 
  perf_push (PERF_MULTI_CREATE_INSTANCE);
631
 
 
632
 
  msg (D_MULTI_LOW, "MULTI: multi_create_instance called");
633
 
 
634
 
  ALLOC_OBJ_CLEAR (mi, struct multi_instance);
635
 
 
636
 
  mi->gc = gc_new ();
637
 
  multi_instance_inc_refcount (mi);
638
 
  mi->vaddr_handle = -1;
639
 
  mi->created = now;
640
 
  mroute_addr_init (&mi->real);
641
 
 
642
 
  if (real)
643
 
    {
644
 
      mi->real = *real;
645
 
      generate_prefix (mi);
646
 
    }
647
 
 
648
 
  mi->did_open_context = true;
649
 
  inherit_context_child (&mi->context, &m->top);
650
 
  if (IS_SIG (&mi->context))
651
 
    goto err;
652
 
 
653
 
  mi->context.c2.context_auth = CAS_PENDING;
654
 
 
655
 
  if (hash_n_elements (m->hash) >= m->max_clients)
656
 
    {
657
 
      msg (D_MULTI_ERRORS, "MULTI: new incoming connection would exceed maximum number of clients (%d)", m->max_clients);
658
 
      goto err;
659
 
    }
660
 
 
661
 
  if (!real) /* TCP mode? */
662
 
    {
663
 
      if (!multi_tcp_instance_specific_init (m, mi))
664
 
        goto err;
665
 
      generate_prefix (mi);
666
 
    }
667
 
 
668
 
  if (!hash_add (m->iter, &mi->real, mi, false))
669
 
    {
670
 
      msg (D_MULTI_LOW, "MULTI: unable to add real address [%s] to iterator hash table",
671
 
           mroute_addr_print (&mi->real, &gc));
672
 
      goto err;
673
 
    }
674
 
  mi->did_iter = true;
675
 
 
676
 
#ifdef MANAGEMENT_DEF_AUTH
677
 
  do {
678
 
    mi->context.c2.mda_context.cid = m->cid_counter++;
679
 
  } while (!hash_add (m->cid_hash, &mi->context.c2.mda_context.cid, mi, false));
680
 
  mi->did_cid_hash = true;
681
 
#endif
682
 
 
683
 
  mi->context.c2.push_reply_deferred = true;
684
 
 
685
 
  if (!multi_process_post (m, mi, MPP_PRE_SELECT))
686
 
    {
687
 
      msg (D_MULTI_ERRORS, "MULTI: signal occurred during client instance initialization");
688
 
      goto err;
689
 
    }
690
 
 
691
 
  perf_pop ();
692
 
  gc_free (&gc);
693
 
  return mi;
694
 
 
695
 
 err:
696
 
  multi_close_instance (m, mi, false);
697
 
  perf_pop ();
698
 
  gc_free (&gc);
699
 
  return NULL;
700
 
}
701
 
 
702
 
/*
703
 
 * Dump tables -- triggered by SIGUSR2.
704
 
 * If status file is defined, write to file.
705
 
 * If status file is NULL, write to syslog.
706
 
 */
707
 
void
708
 
multi_print_status (struct multi_context *m, struct status_output *so, const int version)
709
 
{
710
 
  if (m->hash)
711
 
    {
712
 
      struct gc_arena gc_top = gc_new ();
713
 
      struct hash_iterator hi;
714
 
      const struct hash_element *he;
715
 
 
716
 
      status_reset (so);
717
 
 
718
 
      if (version == 1) /* WAS: m->status_file_version */
719
 
        {
720
 
          /*
721
 
           * Status file version 1
722
 
           */
723
 
          status_printf (so, "OpenVPN CLIENT LIST");
724
 
          status_printf (so, "Updated,%s", time_string (0, 0, false, &gc_top));
725
 
          status_printf (so, "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since");
726
 
          hash_iterator_init (m->hash, &hi);
727
 
          while ((he = hash_iterator_next (&hi)))
728
 
            {
729
 
              struct gc_arena gc = gc_new ();
730
 
              const struct multi_instance *mi = (struct multi_instance *) he->value;
731
 
 
732
 
              if (!mi->halt)
733
 
                {
734
 
                  status_printf (so, "%s,%s," counter_format "," counter_format ",%s",
735
 
                                 tls_common_name (mi->context.c2.tls_multi, false),
736
 
                                 mroute_addr_print (&mi->real, &gc),
737
 
                                 mi->context.c2.link_read_bytes,
738
 
                                 mi->context.c2.link_write_bytes,
739
 
                                 time_string (mi->created, 0, false, &gc));
740
 
                }
741
 
              gc_free (&gc);
742
 
            }
743
 
          hash_iterator_free (&hi);
744
 
 
745
 
          status_printf (so, "ROUTING TABLE");
746
 
          status_printf (so, "Virtual Address,Common Name,Real Address,Last Ref");
747
 
          hash_iterator_init (m->vhash, &hi);
748
 
          while ((he = hash_iterator_next (&hi)))
749
 
            {
750
 
              struct gc_arena gc = gc_new ();
751
 
              const struct multi_route *route = (struct multi_route *) he->value;
752
 
 
753
 
              if (multi_route_defined (m, route))
754
 
                {
755
 
                  const struct multi_instance *mi = route->instance;
756
 
                  const struct mroute_addr *ma = &route->addr;
757
 
                  char flags[2] = {0, 0};
758
 
 
759
 
                  if (route->flags & MULTI_ROUTE_CACHE)
760
 
                    flags[0] = 'C';
761
 
                  status_printf (so, "%s%s,%s,%s,%s",
762
 
                                 mroute_addr_print (ma, &gc),
763
 
                                 flags,
764
 
                                 tls_common_name (mi->context.c2.tls_multi, false),
765
 
                                 mroute_addr_print (&mi->real, &gc),
766
 
                                 time_string (route->last_reference, 0, false, &gc));
767
 
                }
768
 
              gc_free (&gc);
769
 
            }
770
 
          hash_iterator_free (&hi);
771
 
 
772
 
          status_printf (so, "GLOBAL STATS");
773
 
          if (m->mbuf)
774
 
            status_printf (so, "Max bcast/mcast queue length,%d",
775
 
                           mbuf_maximum_queued (m->mbuf));
776
 
 
777
 
          status_printf (so, "END");
778
 
        }
779
 
      else if (version == 2 || version == 3)
780
 
        {
781
 
          const char sep = (version == 3) ? '\t' : ',';
782
 
 
783
 
          /*
784
 
           * Status file version 2 and 3
785
 
           */
786
 
          status_printf (so, "TITLE%c%s", sep, title_string);
787
 
          status_printf (so, "TIME%c%s%c%u", sep, time_string (now, 0, false, &gc_top), sep, (unsigned int)now);
788
 
          status_printf (so, "HEADER%cCLIENT_LIST%cCommon Name%cReal Address%cVirtual Address%cBytes Received%cBytes Sent%cConnected Since%cConnected Since (time_t)",
789
 
                         sep, sep, sep, sep, sep, sep, sep, sep);
790
 
          hash_iterator_init (m->hash, &hi);
791
 
          while ((he = hash_iterator_next (&hi)))
792
 
            {
793
 
              struct gc_arena gc = gc_new ();
794
 
              const struct multi_instance *mi = (struct multi_instance *) he->value;
795
 
 
796
 
              if (!mi->halt)
797
 
                {
798
 
                  status_printf (so, "CLIENT_LIST%c%s%c%s%c%s%c" counter_format "%c" counter_format "%c%s%c%u",
799
 
                                 sep, tls_common_name (mi->context.c2.tls_multi, false),
800
 
                                 sep, mroute_addr_print (&mi->real, &gc),
801
 
                                 sep, print_in_addr_t (mi->reporting_addr, IA_EMPTY_IF_UNDEF, &gc),
802
 
                                 sep, mi->context.c2.link_read_bytes,
803
 
                                 sep, mi->context.c2.link_write_bytes,
804
 
                                 sep, time_string (mi->created, 0, false, &gc),
805
 
                                 sep, (unsigned int)mi->created);
806
 
                }
807
 
              gc_free (&gc);
808
 
            }
809
 
          hash_iterator_free (&hi);
810
 
 
811
 
          status_printf (so, "HEADER%cROUTING_TABLE%cVirtual Address%cCommon Name%cReal Address%cLast Ref%cLast Ref (time_t)",
812
 
                         sep, sep, sep, sep, sep, sep);
813
 
          hash_iterator_init (m->vhash, &hi);
814
 
          while ((he = hash_iterator_next (&hi)))
815
 
            {
816
 
              struct gc_arena gc = gc_new ();
817
 
              const struct multi_route *route = (struct multi_route *) he->value;
818
 
 
819
 
              if (multi_route_defined (m, route))
820
 
                {
821
 
                  const struct multi_instance *mi = route->instance;
822
 
                  const struct mroute_addr *ma = &route->addr;
823
 
                  char flags[2] = {0, 0};
824
 
 
825
 
                  if (route->flags & MULTI_ROUTE_CACHE)
826
 
                    flags[0] = 'C';
827
 
                  status_printf (so, "ROUTING_TABLE%c%s%s%c%s%c%s%c%s%c%u",
828
 
                                 sep, mroute_addr_print (ma, &gc), flags,
829
 
                                 sep, tls_common_name (mi->context.c2.tls_multi, false),
830
 
                                 sep, mroute_addr_print (&mi->real, &gc),
831
 
                                 sep, time_string (route->last_reference, 0, false, &gc),
832
 
                                 sep, (unsigned int)route->last_reference);
833
 
                }
834
 
              gc_free (&gc);
835
 
            }
836
 
          hash_iterator_free (&hi);
837
 
 
838
 
          if (m->mbuf)
839
 
            status_printf (so, "GLOBAL_STATS%cMax bcast/mcast queue length%c%d",
840
 
                           sep, sep, mbuf_maximum_queued (m->mbuf));
841
 
 
842
 
          status_printf (so, "END");
843
 
        }
844
 
      else
845
 
        {
846
 
          status_printf (so, "ERROR: bad status format version number");
847
 
        }
848
 
 
849
 
#ifdef PACKET_TRUNCATION_CHECK
850
 
      {
851
 
        status_printf (so, "HEADER,ERRORS,Common Name,TUN Read Trunc,TUN Write Trunc,Pre-encrypt Trunc,Post-decrypt Trunc");
852
 
        hash_iterator_init (m->hash, &hi);
853
 
        while ((he = hash_iterator_next (&hi)))
854
 
            {
855
 
              struct gc_arena gc = gc_new ();
856
 
              const struct multi_instance *mi = (struct multi_instance *) he->value;
857
 
 
858
 
              if (!mi->halt)
859
 
                {
860
 
                  status_printf (so, "ERRORS,%s," counter_format "," counter_format "," counter_format "," counter_format,
861
 
                                 tls_common_name (mi->context.c2.tls_multi, false),
862
 
                                 m->top.c2.n_trunc_tun_read,
863
 
                                 mi->context.c2.n_trunc_tun_write,
864
 
                                 mi->context.c2.n_trunc_pre_encrypt,
865
 
                                 mi->context.c2.n_trunc_post_decrypt);
866
 
                }
867
 
              gc_free (&gc);
868
 
            }
869
 
        hash_iterator_free (&hi);
870
 
      }
871
 
#endif
872
 
 
873
 
      status_flush (so);
874
 
      gc_free (&gc_top);
875
 
    }
876
 
}
877
 
 
878
 
/*
879
 
 * Learn a virtual address or route.
880
 
 * The learn will fail if the learn address
881
 
 * script/plugin fails.  In this case the
882
 
 * return value may be != mi.
883
 
 * Return the instance which owns this route,
884
 
 * or NULL if none.
885
 
 */
886
 
static struct multi_instance *
887
 
multi_learn_addr (struct multi_context *m,
888
 
                  struct multi_instance *mi,
889
 
                  const struct mroute_addr *addr,
890
 
                  const unsigned int flags)
891
 
{
892
 
  struct hash_element *he;
893
 
  const uint32_t hv = hash_value (m->vhash, addr);
894
 
  struct hash_bucket *bucket = hash_bucket (m->vhash, hv);
895
 
  struct multi_route *oldroute = NULL;
896
 
  struct multi_instance *owner = NULL;
897
 
 
898
 
  /* if route currently exists, get the instance which owns it */
899
 
  he = hash_lookup_fast (m->vhash, bucket, addr, hv);
900
 
  if (he)
901
 
    oldroute = (struct multi_route *) he->value;
902
 
  if (oldroute && multi_route_defined (m, oldroute))
903
 
    owner = oldroute->instance;
904
 
 
905
 
  /* do we need to add address to hash table? */
906
 
  if ((!owner || owner != mi)
907
 
      && mroute_learnable_address (addr)
908
 
      && !mroute_addr_equal (addr, &m->local))
909
 
    {
910
 
      struct gc_arena gc = gc_new ();
911
 
      struct multi_route *newroute;
912
 
      bool learn_succeeded = false;
913
 
 
914
 
      ALLOC_OBJ (newroute, struct multi_route);
915
 
      newroute->addr = *addr;
916
 
      newroute->instance = mi;
917
 
      newroute->flags = flags;
918
 
      newroute->last_reference = now;
919
 
      newroute->cache_generation = 0;
920
 
 
921
 
      /* The cache is invalidated when cache_generation is incremented */
922
 
      if (flags & MULTI_ROUTE_CACHE)
923
 
        newroute->cache_generation = m->route_helper->cache_generation;
924
 
 
925
 
      if (oldroute) /* route already exists? */
926
 
        {
927
 
          if (route_quota_test (m, mi) && learn_address_script (m, mi, "update", &newroute->addr))
928
 
            {
929
 
              learn_succeeded = true;
930
 
              owner = mi;
931
 
              multi_instance_inc_refcount (mi);
932
 
              route_quota_inc (mi);
933
 
 
934
 
              /* delete old route */
935
 
              multi_route_del (oldroute);
936
 
 
937
 
              /* modify hash table entry, replacing old route */
938
 
              he->key = &newroute->addr;
939
 
              he->value = newroute;
940
 
            }
941
 
        }
942
 
      else
943
 
        {
944
 
          if (route_quota_test (m, mi) && learn_address_script (m, mi, "add", &newroute->addr))
945
 
            {
946
 
              learn_succeeded = true;
947
 
              owner = mi;
948
 
              multi_instance_inc_refcount (mi);
949
 
              route_quota_inc (mi);
950
 
 
951
 
              /* add new route */
952
 
              hash_add_fast (m->vhash, bucket, &newroute->addr, hv, newroute);
953
 
            }
954
 
        }
955
 
      
956
 
      msg (D_MULTI_LOW, "MULTI: Learn%s: %s -> %s",
957
 
           learn_succeeded ? "" : " FAILED",
958
 
           mroute_addr_print (&newroute->addr, &gc),
959
 
           multi_instance_string (mi, false, &gc));
960
 
 
961
 
      if (!learn_succeeded)
962
 
        free (newroute);
963
 
 
964
 
      gc_free (&gc);
965
 
    }
966
 
 
967
 
  return owner;
968
 
}
969
 
 
970
 
/*
971
 
 * Get client instance based on virtual address.
972
 
 */
973
 
static struct multi_instance *
974
 
multi_get_instance_by_virtual_addr (struct multi_context *m,
975
 
                                    const struct mroute_addr *addr,
976
 
                                    bool cidr_routing)
977
 
{
978
 
  struct multi_route *route;
979
 
  struct multi_instance *ret = NULL;
980
 
 
981
 
  /* check for local address */
982
 
  if (mroute_addr_equal (addr, &m->local))
983
 
    return NULL;
984
 
 
985
 
  route = (struct multi_route *) hash_lookup (m->vhash, addr);
986
 
 
987
 
  /* does host route (possible cached) exist? */
988
 
  if (route && multi_route_defined (m, route))
989
 
    {
990
 
      struct multi_instance *mi = route->instance;
991
 
      route->last_reference = now;
992
 
      ret = mi;
993
 
    }
994
 
  else if (cidr_routing) /* do we need to regenerate a host route cache entry? */
995
 
    {
996
 
      struct mroute_helper *rh = m->route_helper;
997
 
      struct mroute_addr tryaddr;
998
 
      int i;
999
 
 
1000
 
      /* cycle through each CIDR length */
1001
 
      for (i = 0; i < rh->n_net_len; ++i)
1002
 
        {
1003
 
          tryaddr = *addr;
1004
 
          tryaddr.type |= MR_WITH_NETBITS;
1005
 
          tryaddr.netbits = rh->net_len[i];
1006
 
          mroute_addr_mask_host_bits (&tryaddr);
1007
 
 
1008
 
          /* look up a possible route with netbits netmask */
1009
 
          route = (struct multi_route *) hash_lookup (m->vhash, &tryaddr);
1010
 
 
1011
 
          if (route && multi_route_defined (m, route))
1012
 
            {
1013
 
              /* found an applicable route, cache host route */
1014
 
              struct multi_instance *mi = route->instance;
1015
 
              multi_learn_addr (m, mi, addr, MULTI_ROUTE_CACHE|MULTI_ROUTE_AGEABLE);
1016
 
              ret = mi;
1017
 
              break;
1018
 
            }
1019
 
        }
1020
 
    }
1021
 
  
1022
 
#ifdef ENABLE_DEBUG
1023
 
  if (check_debug_level (D_MULTI_DEBUG))
1024
 
    {
1025
 
      struct gc_arena gc = gc_new ();
1026
 
      const char *addr_text = mroute_addr_print (addr, &gc);
1027
 
      if (ret)
1028
 
        {
1029
 
          dmsg (D_MULTI_DEBUG, "GET INST BY VIRT: %s -> %s via %s",
1030
 
               addr_text,
1031
 
               multi_instance_string (ret, false, &gc),
1032
 
               mroute_addr_print (&route->addr, &gc));
1033
 
        }
1034
 
      else
1035
 
        {
1036
 
          dmsg (D_MULTI_DEBUG, "GET INST BY VIRT: %s [failed]",
1037
 
               addr_text);
1038
 
        }
1039
 
      gc_free (&gc);
1040
 
    }
1041
 
#endif
1042
 
 
1043
 
  ASSERT (!(ret && ret->halt));
1044
 
  return ret;
1045
 
}
1046
 
 
1047
 
/*
1048
 
 * Helper function to multi_learn_addr().
1049
 
 */
1050
 
static struct multi_instance *
1051
 
multi_learn_in_addr_t (struct multi_context *m,
1052
 
                       struct multi_instance *mi,
1053
 
                       in_addr_t a,
1054
 
                       int netbits, /* -1 if host route, otherwise # of network bits in address */
1055
 
                       bool primary)
1056
 
{
1057
 
  struct openvpn_sockaddr remote_si;
1058
 
  struct mroute_addr addr;
1059
 
 
1060
 
  CLEAR (remote_si);
1061
 
  remote_si.sa.sin_family = AF_INET;
1062
 
  remote_si.sa.sin_addr.s_addr = htonl (a);
1063
 
  ASSERT (mroute_extract_openvpn_sockaddr (&addr, &remote_si, false));
1064
 
 
1065
 
  if (netbits >= 0)
1066
 
    {
1067
 
      addr.type |= MR_WITH_NETBITS;
1068
 
      addr.netbits = (uint8_t) netbits;
1069
 
    }
1070
 
 
1071
 
  {
1072
 
    struct multi_instance *owner = multi_learn_addr (m, mi, &addr, 0);
1073
 
#ifdef MANAGEMENT_DEF_AUTH
1074
 
    if (management && owner)
1075
 
      management_learn_addr (management, &mi->context.c2.mda_context, &addr, primary);
1076
 
#endif
1077
 
    return owner;
1078
 
  }
1079
 
}
1080
 
 
1081
 
/*
1082
 
 * A new client has connected, add routes (server -> client)
1083
 
 * to internal routing table.
1084
 
 */
1085
 
static void
1086
 
multi_add_iroutes (struct multi_context *m,
1087
 
                   struct multi_instance *mi)
1088
 
{
1089
 
  struct gc_arena gc = gc_new ();
1090
 
  const struct iroute *ir;
1091
 
  if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
1092
 
    {
1093
 
      mi->did_iroutes = true;
1094
 
      for (ir = mi->context.options.iroutes; ir != NULL; ir = ir->next)
1095
 
        {
1096
 
          if (ir->netbits >= 0)
1097
 
            msg (D_MULTI_LOW, "MULTI: internal route %s/%d -> %s",
1098
 
                 print_in_addr_t (ir->network, 0, &gc),
1099
 
                 ir->netbits,
1100
 
                 multi_instance_string (mi, false, &gc));
1101
 
          else
1102
 
            msg (D_MULTI_LOW, "MULTI: internal route %s -> %s",
1103
 
                 print_in_addr_t (ir->network, 0, &gc),
1104
 
                 multi_instance_string (mi, false, &gc));
1105
 
 
1106
 
          mroute_helper_add_iroute (m->route_helper, ir);
1107
 
      
1108
 
          multi_learn_in_addr_t (m, mi, ir->network, ir->netbits, false);
1109
 
        }
1110
 
    }
1111
 
  gc_free (&gc);
1112
 
}
1113
 
 
1114
 
/*
1115
 
 * Given an instance (new_mi), delete all other instances which use the
1116
 
 * same common name.
1117
 
 */
1118
 
static void
1119
 
multi_delete_dup (struct multi_context *m, struct multi_instance *new_mi)
1120
 
{
1121
 
  if (new_mi)
1122
 
    {
1123
 
      const char *new_cn = tls_common_name (new_mi->context.c2.tls_multi, true);
1124
 
      if (new_cn)
1125
 
        {
1126
 
          struct hash_iterator hi;
1127
 
          struct hash_element *he;
1128
 
          int count = 0;
1129
 
 
1130
 
          hash_iterator_init (m->iter, &hi);
1131
 
          while ((he = hash_iterator_next (&hi)))
1132
 
            {
1133
 
              struct multi_instance *mi = (struct multi_instance *) he->value;
1134
 
              if (mi != new_mi && !mi->halt)
1135
 
                {
1136
 
                  const char *cn = tls_common_name (mi->context.c2.tls_multi, true);
1137
 
                  if (cn && !strcmp (cn, new_cn))
1138
 
                    {
1139
 
                      mi->did_iter = false;
1140
 
                      multi_close_instance (m, mi, false);
1141
 
                      hash_iterator_delete_element (&hi);
1142
 
                      ++count;
1143
 
                    }
1144
 
                }
1145
 
            }
1146
 
          hash_iterator_free (&hi);
1147
 
 
1148
 
          if (count)
1149
 
            msg (D_MULTI_LOW, "MULTI: new connection by client '%s' will cause previous active sessions by this client to be dropped.  Remember to use the --duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect.", new_cn);
1150
 
        }
1151
 
    }
1152
 
}
1153
 
 
1154
 
/*
1155
 
 * Ensure that endpoint to be pushed to client
1156
 
 * complies with --ifconfig-push-constraint directive.
1157
 
 */
1158
 
static bool
1159
 
ifconfig_push_constraint_satisfied (const struct context *c)
1160
 
{
1161
 
  const struct options *o = &c->options;
1162
 
  if (o->push_ifconfig_constraint_defined && c->c2.push_ifconfig_defined)
1163
 
    return (o->push_ifconfig_constraint_netmask & c->c2.push_ifconfig_local) == o->push_ifconfig_constraint_network;
1164
 
  else
1165
 
    return true;
1166
 
}
1167
 
 
1168
 
/*
1169
 
 * Select a virtual address for a new client instance.
1170
 
 * Use an --ifconfig-push directive, if given (static IP).
1171
 
 * Otherwise use an --ifconfig-pool address (dynamic IP). 
1172
 
 */
1173
 
static void
1174
 
multi_select_virtual_addr (struct multi_context *m, struct multi_instance *mi)
1175
 
{
1176
 
  struct gc_arena gc = gc_new ();
1177
 
 
1178
 
  /*
1179
 
   * If ifconfig addresses were set by dynamic config file,
1180
 
   * release pool addresses, otherwise keep them.
1181
 
   */
1182
 
  if (mi->context.options.push_ifconfig_defined)
1183
 
    {
1184
 
      /* ifconfig addresses were set statically,
1185
 
         release dynamic allocation */
1186
 
      if (mi->vaddr_handle >= 0)
1187
 
        {
1188
 
          ifconfig_pool_release (m->ifconfig_pool, mi->vaddr_handle, true);
1189
 
          mi->vaddr_handle = -1;
1190
 
        }
1191
 
 
1192
 
      mi->context.c2.push_ifconfig_defined = true;
1193
 
      mi->context.c2.push_ifconfig_local = mi->context.options.push_ifconfig_local;
1194
 
      mi->context.c2.push_ifconfig_remote_netmask = mi->context.options.push_ifconfig_remote_netmask;
1195
 
    }
1196
 
  else if (m->ifconfig_pool && mi->vaddr_handle < 0) /* otherwise, choose a pool address */
1197
 
    {
1198
 
      in_addr_t local=0, remote=0;
1199
 
      const char *cn = NULL;
1200
 
 
1201
 
      if (!mi->context.options.duplicate_cn)
1202
 
        cn = tls_common_name (mi->context.c2.tls_multi, true);
1203
 
 
1204
 
      mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, cn);
1205
 
      if (mi->vaddr_handle >= 0)
1206
 
        {
1207
 
          const int tunnel_type = TUNNEL_TYPE (mi->context.c1.tuntap);
1208
 
          const int tunnel_topology = TUNNEL_TOPOLOGY (mi->context.c1.tuntap);
1209
 
 
1210
 
          /* set push_ifconfig_remote_netmask from pool ifconfig address(es) */
1211
 
          mi->context.c2.push_ifconfig_local = remote;
1212
 
          if (tunnel_type == DEV_TYPE_TAP || (tunnel_type == DEV_TYPE_TUN && tunnel_topology == TOP_SUBNET))
1213
 
            {
1214
 
              mi->context.c2.push_ifconfig_remote_netmask = mi->context.options.ifconfig_pool_netmask;
1215
 
              if (!mi->context.c2.push_ifconfig_remote_netmask)
1216
 
                mi->context.c2.push_ifconfig_remote_netmask = mi->context.c1.tuntap->remote_netmask;
1217
 
            }
1218
 
          else if (tunnel_type == DEV_TYPE_TUN)
1219
 
            {
1220
 
              if (tunnel_topology == TOP_P2P)               
1221
 
                mi->context.c2.push_ifconfig_remote_netmask = mi->context.c1.tuntap->local;
1222
 
              else if (tunnel_topology == TOP_NET30)                
1223
 
                mi->context.c2.push_ifconfig_remote_netmask = local;
1224
 
            }
1225
 
 
1226
 
          if (mi->context.c2.push_ifconfig_remote_netmask)
1227
 
            mi->context.c2.push_ifconfig_defined = true;
1228
 
          else
1229
 
            msg (D_MULTI_ERRORS, "MULTI: no --ifconfig-pool netmask parameter is available to push to %s",
1230
 
                 multi_instance_string (mi, false, &gc));
1231
 
        }
1232
 
      else
1233
 
        {
1234
 
          msg (D_MULTI_ERRORS, "MULTI: no free --ifconfig-pool addresses are available");
1235
 
        }
1236
 
    }
1237
 
  gc_free (&gc);
1238
 
}
1239
 
 
1240
 
/*
1241
 
 * Set virtual address environmental variables.
1242
 
 */
1243
 
static void
1244
 
multi_set_virtual_addr_env (struct multi_context *m, struct multi_instance *mi)
1245
 
{
1246
 
  setenv_del (mi->context.c2.es, "ifconfig_pool_local_ip");
1247
 
  setenv_del (mi->context.c2.es, "ifconfig_pool_remote_ip");
1248
 
  setenv_del (mi->context.c2.es, "ifconfig_pool_netmask");
1249
 
 
1250
 
  if (mi->context.c2.push_ifconfig_defined)
1251
 
    {
1252
 
      const int tunnel_type = TUNNEL_TYPE (mi->context.c1.tuntap);
1253
 
      const int tunnel_topology = TUNNEL_TOPOLOGY (mi->context.c1.tuntap);
1254
 
 
1255
 
      setenv_in_addr_t (mi->context.c2.es,
1256
 
                        "ifconfig_pool_remote_ip",
1257
 
                        mi->context.c2.push_ifconfig_local,
1258
 
                        SA_SET_IF_NONZERO);
1259
 
 
1260
 
      if (tunnel_type == DEV_TYPE_TAP || (tunnel_type == DEV_TYPE_TUN && tunnel_topology == TOP_SUBNET))
1261
 
        {
1262
 
          setenv_in_addr_t (mi->context.c2.es,
1263
 
                            "ifconfig_pool_netmask",
1264
 
                            mi->context.c2.push_ifconfig_remote_netmask,
1265
 
                            SA_SET_IF_NONZERO);
1266
 
        }
1267
 
      else if (tunnel_type == DEV_TYPE_TUN)
1268
 
        {
1269
 
          setenv_in_addr_t (mi->context.c2.es,
1270
 
                            "ifconfig_pool_local_ip",
1271
 
                            mi->context.c2.push_ifconfig_remote_netmask,
1272
 
                            SA_SET_IF_NONZERO);
1273
 
        }
1274
 
    }
1275
 
}
1276
 
 
1277
 
/*
1278
 
 * Called after client-connect script is called
1279
 
 */
1280
 
static void
1281
 
multi_client_connect_post (struct multi_context *m,
1282
 
                           struct multi_instance *mi,
1283
 
                           const char *dc_file,
1284
 
                           unsigned int option_permissions_mask,
1285
 
                           unsigned int *option_types_found)
1286
 
{
1287
 
  /* Did script generate a dynamic config file? */
1288
 
  if (test_file (dc_file))
1289
 
    {
1290
 
      options_server_import (&mi->context.options,
1291
 
                             dc_file,
1292
 
                             D_IMPORT_ERRORS|M_OPTERR,
1293
 
                             option_permissions_mask,
1294
 
                             option_types_found,
1295
 
                             mi->context.c2.es);
1296
 
 
1297
 
      if (!delete_file (dc_file))
1298
 
        msg (D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
1299
 
             dc_file);
1300
 
 
1301
 
      /*
1302
 
       * If the --client-connect script generates a config file
1303
 
       * with an --ifconfig-push directive, it will override any
1304
 
       * --ifconfig-push directive from the --client-config-dir
1305
 
       * directory or any --ifconfig-pool dynamic address.
1306
 
       */
1307
 
      multi_select_virtual_addr (m, mi);
1308
 
      multi_set_virtual_addr_env (m, mi);
1309
 
    }
1310
 
}
1311
 
 
1312
 
#ifdef ENABLE_PLUGIN
1313
 
 
1314
 
/*
1315
 
 * Called after client-connect plug-in is called
1316
 
 */
1317
 
static void
1318
 
multi_client_connect_post_plugin (struct multi_context *m,
1319
 
                                  struct multi_instance *mi,
1320
 
                                  const struct plugin_return *pr,
1321
 
                                  unsigned int option_permissions_mask,
1322
 
                                  unsigned int *option_types_found)
1323
 
{
1324
 
  struct plugin_return config;
1325
 
 
1326
 
  plugin_return_get_column (pr, &config, "config");
1327
 
 
1328
 
  /* Did script generate a dynamic config file? */
1329
 
  if (plugin_return_defined (&config))
1330
 
    {
1331
 
      int i;
1332
 
      for (i = 0; i < config.n; ++i)
1333
 
        {
1334
 
          if (config.list[i] && config.list[i]->value)
1335
 
            options_string_import (&mi->context.options,
1336
 
                                   config.list[i]->value,
1337
 
                                   D_IMPORT_ERRORS|M_OPTERR,
1338
 
                                   option_permissions_mask,
1339
 
                                   option_types_found,
1340
 
                                   mi->context.c2.es);
1341
 
        }
1342
 
 
1343
 
      /*
1344
 
       * If the --client-connect script generates a config file
1345
 
       * with an --ifconfig-push directive, it will override any
1346
 
       * --ifconfig-push directive from the --client-config-dir
1347
 
       * directory or any --ifconfig-pool dynamic address.
1348
 
       */
1349
 
      multi_select_virtual_addr (m, mi);
1350
 
      multi_set_virtual_addr_env (m, mi);
1351
 
    }
1352
 
}
1353
 
 
1354
 
#endif
1355
 
 
1356
 
#ifdef MANAGEMENT_DEF_AUTH
1357
 
 
1358
 
/*
1359
 
 * Called to load management-derived client-connect config
1360
 
 */
1361
 
static void
1362
 
multi_client_connect_mda (struct multi_context *m,
1363
 
                          struct multi_instance *mi,
1364
 
                          const struct buffer_list *config,
1365
 
                          unsigned int option_permissions_mask,
1366
 
                          unsigned int *option_types_found)
1367
 
{
1368
 
  if (config)
1369
 
    {
1370
 
      struct buffer_entry *be;
1371
 
  
1372
 
      for (be = config->head; be != NULL; be = be->next)
1373
 
        {
1374
 
          const char *opt = BSTR(&be->buf);
1375
 
          options_string_import (&mi->context.options,
1376
 
                                 opt,
1377
 
                                 D_IMPORT_ERRORS|M_OPTERR,
1378
 
                                 option_permissions_mask,
1379
 
                                 option_types_found,
1380
 
                                 mi->context.c2.es);
1381
 
        }
1382
 
 
1383
 
      /*
1384
 
       * If the --client-connect script generates a config file
1385
 
       * with an --ifconfig-push directive, it will override any
1386
 
       * --ifconfig-push directive from the --client-config-dir
1387
 
       * directory or any --ifconfig-pool dynamic address.
1388
 
       */
1389
 
      multi_select_virtual_addr (m, mi);
1390
 
      multi_set_virtual_addr_env (m, mi);
1391
 
    }
1392
 
}
1393
 
 
1394
 
#endif
1395
 
 
1396
 
static void
1397
 
multi_client_connect_setenv (struct multi_context *m,
1398
 
                             struct multi_instance *mi)
1399
 
{
1400
 
  struct gc_arena gc = gc_new ();
1401
 
 
1402
 
  /* setenv incoming cert common name for script */
1403
 
  setenv_str (mi->context.c2.es, "common_name", tls_common_name (mi->context.c2.tls_multi, true));
1404
 
 
1405
 
  /* setenv client real IP address */
1406
 
  setenv_trusted (mi->context.c2.es, get_link_socket_info (&mi->context));
1407
 
 
1408
 
  /* setenv client virtual IP address */
1409
 
  multi_set_virtual_addr_env (m, mi);
1410
 
 
1411
 
  /* setenv connection time */
1412
 
  {
1413
 
    const char *created_ascii = time_string (mi->created, 0, false, &gc);
1414
 
    setenv_str (mi->context.c2.es, "time_ascii", created_ascii);
1415
 
    setenv_unsigned (mi->context.c2.es, "time_unix", (unsigned int)mi->created);
1416
 
  }
1417
 
 
1418
 
  gc_free (&gc);
1419
 
}
1420
 
 
1421
 
/*
1422
 
 * Called as soon as the SSL/TLS connection authenticates.
1423
 
 *
1424
 
 * Instance-specific directives to be processed:
1425
 
 *
1426
 
 *   iroute start-ip end-ip
1427
 
 *   ifconfig-push local remote-netmask
1428
 
 *   push
1429
 
 */
1430
 
static void
1431
 
multi_connection_established (struct multi_context *m, struct multi_instance *mi)
1432
 
{
1433
 
  if (tls_authentication_status (mi->context.c2.tls_multi, 0) == TLS_AUTHENTICATION_SUCCEEDED)
1434
 
    {
1435
 
      struct gc_arena gc = gc_new ();
1436
 
      unsigned int option_types_found = 0;
1437
 
 
1438
 
      const unsigned int option_permissions_mask =
1439
 
          OPT_P_INSTANCE
1440
 
        | OPT_P_INHERIT
1441
 
        | OPT_P_PUSH
1442
 
        | OPT_P_TIMER
1443
 
        | OPT_P_CONFIG
1444
 
        | OPT_P_ECHO
1445
 
        | OPT_P_COMP
1446
 
        | OPT_P_SOCKFLAGS;
1447
 
 
1448
 
      int cc_succeeded = true; /* client connect script status */
1449
 
      int cc_succeeded_count = 0;
1450
 
 
1451
 
      ASSERT (mi->context.c1.tuntap);
1452
 
 
1453
 
      /* lock down the common name and cert hashes so they can't change during future TLS renegotiations */
1454
 
      tls_lock_common_name (mi->context.c2.tls_multi);
1455
 
      tls_lock_cert_hash_set (mi->context.c2.tls_multi);
1456
 
 
1457
 
      /* generate a msg() prefix for this client instance */
1458
 
      generate_prefix (mi);
1459
 
 
1460
 
      /* delete instances of previous clients with same common-name */
1461
 
      if (!mi->context.options.duplicate_cn)
1462
 
        multi_delete_dup (m, mi);
1463
 
 
1464
 
      /* reset pool handle to null */
1465
 
      mi->vaddr_handle = -1;
1466
 
 
1467
 
      /*
1468
 
       * Try to source a dynamic config file from the
1469
 
       * --client-config-dir directory.
1470
 
       */
1471
 
      if (mi->context.options.client_config_dir)
1472
 
        {
1473
 
          const char *ccd_file;
1474
 
          
1475
 
          ccd_file = gen_path (mi->context.options.client_config_dir,
1476
 
                               tls_common_name (mi->context.c2.tls_multi, false),
1477
 
                               &gc);
1478
 
 
1479
 
          /* try common-name file */
1480
 
          if (test_file (ccd_file))
1481
 
            {
1482
 
              options_server_import (&mi->context.options,
1483
 
                                     ccd_file,
1484
 
                                     D_IMPORT_ERRORS|M_OPTERR,
1485
 
                                     option_permissions_mask,
1486
 
                                     &option_types_found,
1487
 
                                     mi->context.c2.es);
1488
 
            }
1489
 
          else /* try default file */
1490
 
            {
1491
 
              ccd_file = gen_path (mi->context.options.client_config_dir,
1492
 
                                   CCD_DEFAULT,
1493
 
                                   &gc);
1494
 
 
1495
 
              if (test_file (ccd_file))
1496
 
                {
1497
 
                  options_server_import (&mi->context.options,
1498
 
                                         ccd_file,
1499
 
                                         D_IMPORT_ERRORS|M_OPTERR,
1500
 
                                         option_permissions_mask,
1501
 
                                         &option_types_found,
1502
 
                                         mi->context.c2.es);
1503
 
                }
1504
 
            }
1505
 
        }
1506
 
 
1507
 
      /*
1508
 
       * Select a virtual address from either --ifconfig-push in --client-config-dir file
1509
 
       * or --ifconfig-pool.
1510
 
       */
1511
 
      multi_select_virtual_addr (m, mi);
1512
 
 
1513
 
      /* do --client-connect setenvs */
1514
 
      multi_client_connect_setenv (m, mi);
1515
 
 
1516
 
#ifdef ENABLE_PLUGIN
1517
 
      /*
1518
 
       * Call client-connect plug-in.
1519
 
       */
1520
 
 
1521
 
      /* deprecated callback, use a file for passing back return info */
1522
 
      if (plugin_defined (mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT))
1523
 
        {
1524
 
          struct argv argv = argv_new ();
1525
 
          const char *dc_file = create_temp_file (mi->context.options.tmp_dir, "cc", &gc);
1526
 
 
1527
 
          if( !dc_file ) {
1528
 
            cc_succeeded = false;
1529
 
            goto script_depr_failed;
1530
 
          }
1531
 
 
1532
 
          argv_printf (&argv, "%s", dc_file);
1533
 
          if (plugin_call (mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT, &argv, NULL, mi->context.c2.es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
1534
 
            {
1535
 
              msg (M_WARN, "WARNING: client-connect plugin call failed");
1536
 
              cc_succeeded = false;
1537
 
            }
1538
 
          else
1539
 
            {
1540
 
              multi_client_connect_post (m, mi, dc_file, option_permissions_mask, &option_types_found);
1541
 
              ++cc_succeeded_count;
1542
 
            }
1543
 
        script_depr_failed:
1544
 
          argv_reset (&argv);
1545
 
        }
1546
 
 
1547
 
      /* V2 callback, use a plugin_return struct for passing back return info */
1548
 
      if (plugin_defined (mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT_V2))
1549
 
        {
1550
 
          struct plugin_return pr;
1551
 
 
1552
 
          plugin_return_init (&pr);
1553
 
 
1554
 
          if (plugin_call (mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT_V2, NULL, &pr, mi->context.c2.es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
1555
 
            {
1556
 
              msg (M_WARN, "WARNING: client-connect-v2 plugin call failed");
1557
 
              cc_succeeded = false;
1558
 
            }
1559
 
          else
1560
 
            {
1561
 
              multi_client_connect_post_plugin (m, mi, &pr, option_permissions_mask, &option_types_found);
1562
 
              ++cc_succeeded_count;
1563
 
            }
1564
 
 
1565
 
          plugin_return_free (&pr);
1566
 
        }
1567
 
#endif
1568
 
 
1569
 
      /*
1570
 
       * Run --client-connect script.
1571
 
       */
1572
 
      if (mi->context.options.client_connect_script && cc_succeeded)
1573
 
        {
1574
 
          struct argv argv = argv_new ();
1575
 
          const char *dc_file = NULL;
1576
 
 
1577
 
          setenv_str (mi->context.c2.es, "script_type", "client-connect");
1578
 
 
1579
 
          dc_file = create_temp_file (mi->context.options.tmp_dir, "cc", &gc);
1580
 
          if( !dc_file ) {
1581
 
            cc_succeeded = false;
1582
 
            goto script_failed;
1583
 
          }
1584
 
 
1585
 
          argv_printf (&argv, "%sc %s",
1586
 
                       mi->context.options.client_connect_script,
1587
 
                       dc_file);
1588
 
 
1589
 
          if (openvpn_run_script (&argv, mi->context.c2.es, 0, "--client-connect"))
1590
 
            {
1591
 
              multi_client_connect_post (m, mi, dc_file, option_permissions_mask, &option_types_found);
1592
 
              ++cc_succeeded_count;
1593
 
            }
1594
 
          else
1595
 
            cc_succeeded = false;
1596
 
        script_failed:
1597
 
          argv_reset (&argv);
1598
 
        }
1599
 
 
1600
 
      /*
1601
 
       * Check for client-connect script left by management interface client
1602
 
       */
1603
 
#ifdef MANAGEMENT_DEF_AUTH
1604
 
      if (cc_succeeded && mi->cc_config)
1605
 
        {
1606
 
          multi_client_connect_mda (m, mi, mi->cc_config, option_permissions_mask, &option_types_found);
1607
 
          ++cc_succeeded_count;
1608
 
        }
1609
 
#endif
1610
 
 
1611
 
      /*
1612
 
       * Check for "disable" directive in client-config-dir file
1613
 
       * or config file generated by --client-connect script.
1614
 
       */
1615
 
      if (mi->context.options.disable)
1616
 
        {
1617
 
          msg (D_MULTI_ERRORS, "MULTI: client has been rejected due to 'disable' directive");
1618
 
          cc_succeeded = false;
1619
 
        }
1620
 
 
1621
 
      if (cc_succeeded)
1622
 
        {
1623
 
          /*
1624
 
           * Process sourced options.
1625
 
           */
1626
 
          do_deferred_options (&mi->context, option_types_found);
1627
 
 
1628
 
          /*
1629
 
           * make sure we got ifconfig settings from somewhere
1630
 
           */
1631
 
          if (!mi->context.c2.push_ifconfig_defined)
1632
 
            {
1633
 
              msg (D_MULTI_ERRORS, "MULTI: no dynamic or static remote --ifconfig address is available for %s",
1634
 
                   multi_instance_string (mi, false, &gc));
1635
 
            }
1636
 
 
1637
 
          /*
1638
 
           * make sure that ifconfig settings comply with constraints
1639
 
           */
1640
 
          if (!ifconfig_push_constraint_satisfied (&mi->context))
1641
 
            {
1642
 
              /* JYFIXME -- this should cause the connection to fail */
1643
 
              msg (D_MULTI_ERRORS, "MULTI ERROR: primary virtual IP for %s (%s) violates tunnel network/netmask constraint (%s/%s)",
1644
 
                   multi_instance_string (mi, false, &gc),
1645
 
                   print_in_addr_t (mi->context.c2.push_ifconfig_local, 0, &gc),
1646
 
                   print_in_addr_t (mi->context.options.push_ifconfig_constraint_network, 0, &gc),
1647
 
                   print_in_addr_t (mi->context.options.push_ifconfig_constraint_netmask, 0, &gc));
1648
 
            }
1649
 
 
1650
 
          /*
1651
 
           * For routed tunnels, set up internal route to endpoint
1652
 
           * plus add all iroute routes.
1653
 
           */
1654
 
          if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
1655
 
            {
1656
 
              if (mi->context.c2.push_ifconfig_defined)
1657
 
                {
1658
 
                  multi_learn_in_addr_t (m, mi, mi->context.c2.push_ifconfig_local, -1, true);
1659
 
                  msg (D_MULTI_LOW, "MULTI: primary virtual IP for %s: %s",
1660
 
                       multi_instance_string (mi, false, &gc),
1661
 
                       print_in_addr_t (mi->context.c2.push_ifconfig_local, 0, &gc));
1662
 
                }
1663
 
 
1664
 
              /* add routes locally, pointing to new client, if
1665
 
                 --iroute options have been specified */
1666
 
              multi_add_iroutes (m, mi);
1667
 
 
1668
 
              /*
1669
 
               * iroutes represent subnets which are "owned" by a particular
1670
 
               * client.  Therefore, do not actually push a route to a client
1671
 
               * if it matches one of the client's iroutes.
1672
 
               */
1673
 
              remove_iroutes_from_push_route_list (&mi->context.options);
1674
 
            }
1675
 
          else if (mi->context.options.iroutes)
1676
 
            {
1677
 
              msg (D_MULTI_ERRORS, "MULTI: --iroute options rejected for %s -- iroute only works with tun-style tunnels",
1678
 
                   multi_instance_string (mi, false, &gc));
1679
 
            }
1680
 
 
1681
 
          /* set our client's VPN endpoint for status reporting purposes */
1682
 
          mi->reporting_addr = mi->context.c2.push_ifconfig_local;
1683
 
 
1684
 
          /* set context-level authentication flag */
1685
 
          mi->context.c2.context_auth = CAS_SUCCEEDED;
1686
 
        }
1687
 
      else
1688
 
        {
1689
 
          /* set context-level authentication flag */
1690
 
          mi->context.c2.context_auth = cc_succeeded_count ? CAS_PARTIAL : CAS_FAILED;
1691
 
        }
1692
 
 
1693
 
      /* set flag so we don't get called again */
1694
 
      mi->connection_established_flag = true;
1695
 
 
1696
 
      /* increment number of current authenticated clients */
1697
 
      ++m->n_clients;
1698
 
      --mi->n_clients_delta;
1699
 
 
1700
 
#ifdef MANAGEMENT_DEF_AUTH
1701
 
      if (management)
1702
 
        management_connection_established (management, &mi->context.c2.mda_context, mi->context.c2.es);
1703
 
#endif
1704
 
 
1705
 
      gc_free (&gc);
1706
 
    }
1707
 
 
1708
 
  /*
1709
 
   * Reply now to client's PUSH_REQUEST query
1710
 
   */
1711
 
  mi->context.c2.push_reply_deferred = false;
1712
 
}
1713
 
 
1714
 
/*
1715
 
 * Add a mbuf buffer to a particular
1716
 
 * instance.
1717
 
 */
1718
 
void
1719
 
multi_add_mbuf (struct multi_context *m,
1720
 
                struct multi_instance *mi,
1721
 
                struct mbuf_buffer *mb)
1722
 
{
1723
 
  if (multi_output_queue_ready (m, mi))
1724
 
    {
1725
 
      struct mbuf_item item;
1726
 
      item.buffer = mb;
1727
 
      item.instance = mi;
1728
 
      mbuf_add_item (m->mbuf, &item);
1729
 
    }
1730
 
  else
1731
 
    {
1732
 
      msg (D_MULTI_DROPPED, "MULTI: packet dropped due to output saturation (multi_add_mbuf)");
1733
 
    }
1734
 
}
1735
 
 
1736
 
/*
1737
 
 * Add a packet to a client instance output queue.
1738
 
 */
1739
 
static inline void
1740
 
multi_unicast (struct multi_context *m,
1741
 
               const struct buffer *buf,
1742
 
               struct multi_instance *mi)
1743
 
{
1744
 
  struct mbuf_buffer *mb;
1745
 
 
1746
 
  if (BLEN (buf) > 0)
1747
 
    {
1748
 
      mb = mbuf_alloc_buf (buf);
1749
 
      mb->flags = MF_UNICAST;
1750
 
      multi_add_mbuf (m, mi, mb);
1751
 
      mbuf_free_buf (mb);
1752
 
    }
1753
 
}
1754
 
 
1755
 
/*
1756
 
 * Broadcast a packet to all clients.
1757
 
 */
1758
 
static void
1759
 
multi_bcast (struct multi_context *m,
1760
 
             const struct buffer *buf,
1761
 
             const struct multi_instance *sender_instance,
1762
 
             const struct mroute_addr *sender_addr)
1763
 
{
1764
 
  struct hash_iterator hi;
1765
 
  struct hash_element *he;
1766
 
  struct multi_instance *mi;
1767
 
  struct mbuf_buffer *mb;
1768
 
 
1769
 
  if (BLEN (buf) > 0)
1770
 
    {
1771
 
      perf_push (PERF_MULTI_BCAST);
1772
 
#ifdef MULTI_DEBUG_EVENT_LOOP
1773
 
      printf ("BCAST len=%d\n", BLEN (buf));
1774
 
#endif
1775
 
      mb = mbuf_alloc_buf (buf);
1776
 
      hash_iterator_init (m->iter, &hi);
1777
 
 
1778
 
      while ((he = hash_iterator_next (&hi)))
1779
 
        {
1780
 
          mi = (struct multi_instance *) he->value;
1781
 
          if (mi != sender_instance && !mi->halt)
1782
 
            {
1783
 
#ifdef ENABLE_PF
1784
 
              if (sender_instance)
1785
 
                {
1786
 
                  if (!pf_c2c_test (&sender_instance->context, &mi->context, "bcast_c2c"))
1787
 
                    {
1788
 
                      msg (D_PF_DROPPED_BCAST, "PF: client[%s] -> client[%s] packet dropped by BCAST packet filter",
1789
 
                           mi_prefix (sender_instance),
1790
 
                           mi_prefix (mi));
1791
 
                      continue;
1792
 
                    }
1793
 
                }
1794
 
              if (sender_addr)
1795
 
                {
1796
 
                  if (!pf_addr_test (&mi->context, sender_addr, "bcast_src_addr"))
1797
 
                    {
1798
 
                      struct gc_arena gc = gc_new ();
1799
 
                      msg (D_PF_DROPPED_BCAST, "PF: addr[%s] -> client[%s] packet dropped by BCAST packet filter",
1800
 
                           mroute_addr_print_ex (sender_addr, MAPF_SHOW_ARP, &gc),
1801
 
                           mi_prefix (mi));
1802
 
                      gc_free (&gc);
1803
 
                      continue;
1804
 
                    }
1805
 
                }
1806
 
#endif
1807
 
              multi_add_mbuf (m, mi, mb);
1808
 
            }
1809
 
        }
1810
 
 
1811
 
      hash_iterator_free (&hi);
1812
 
      mbuf_free_buf (mb);
1813
 
      perf_pop ();
1814
 
    }
1815
 
}
1816
 
 
1817
 
/*
1818
 
 * Given a time delta, indicating that we wish to be
1819
 
 * awoken by the scheduler at time now + delta, figure
1820
 
 * a sigma parameter (in microseconds) that represents
1821
 
 * a sort of fuzz factor around delta, so that we're
1822
 
 * really telling the scheduler to wake us up any time
1823
 
 * between now + delta - sigma and now + delta + sigma.
1824
 
 *
1825
 
 * The sigma parameter helps the scheduler to run more efficiently.
1826
 
 * Sigma should be no larger than TV_WITHIN_SIGMA_MAX_USEC
1827
 
 */
1828
 
static inline unsigned int
1829
 
compute_wakeup_sigma (const struct timeval *delta)
1830
 
{
1831
 
  if (delta->tv_sec < 1)
1832
 
    {
1833
 
      /* if < 1 sec, fuzz = # of microseconds / 8 */
1834
 
      return delta->tv_usec >> 3;
1835
 
    }
1836
 
  else
1837
 
    {
1838
 
      /* if < 10 minutes, fuzz = 13.1% of timeout */
1839
 
      if (delta->tv_sec < 600)
1840
 
        return delta->tv_sec << 17;
1841
 
      else
1842
 
        return 120000000; /* if >= 10 minutes, fuzz = 2 minutes */
1843
 
    }
1844
 
}
1845
 
 
1846
 
static void
1847
 
multi_schedule_context_wakeup (struct multi_context *m, struct multi_instance *mi)
1848
 
{
1849
 
  /* calculate an absolute wakeup time */
1850
 
  ASSERT (!openvpn_gettimeofday (&mi->wakeup, NULL));
1851
 
  tv_add (&mi->wakeup, &mi->context.c2.timeval);
1852
 
 
1853
 
  /* tell scheduler to wake us up at some point in the future */
1854
 
  schedule_add_entry (m->schedule,
1855
 
                      (struct schedule_entry *) mi,
1856
 
                      &mi->wakeup,
1857
 
                      compute_wakeup_sigma (&mi->context.c2.timeval));
1858
 
}
1859
 
 
1860
 
/*
1861
 
 * Figure instance-specific timers, convert
1862
 
 * earliest to absolute time in mi->wakeup,
1863
 
 * call scheduler with our future wakeup time.
1864
 
 *
1865
 
 * Also close context on signal.
1866
 
 */
1867
 
bool
1868
 
multi_process_post (struct multi_context *m, struct multi_instance *mi, const unsigned int flags)
1869
 
{
1870
 
  bool ret = true;
1871
 
 
1872
 
  if (!IS_SIG (&mi->context) && ((flags & MPP_PRE_SELECT) || ((flags & MPP_CONDITIONAL_PRE_SELECT) && !ANY_OUT (&mi->context))))
1873
 
    {
1874
 
      /* figure timeouts and fetch possible outgoing
1875
 
         to_link packets (such as ping or TLS control) */
1876
 
      pre_select (&mi->context);
1877
 
 
1878
 
      if (!IS_SIG (&mi->context))
1879
 
        {
1880
 
          /* tell scheduler to wake us up at some point in the future */
1881
 
          multi_schedule_context_wakeup(m, mi);
1882
 
 
1883
 
          /* connection is "established" when SSL/TLS key negotiation succeeds
1884
 
             and (if specified) auth user/pass succeeds */
1885
 
          if (!mi->connection_established_flag && CONNECTION_ESTABLISHED (&mi->context))
1886
 
            multi_connection_established (m, mi);
1887
 
        }
1888
 
    }
1889
 
 
1890
 
  if (IS_SIG (&mi->context))
1891
 
    {
1892
 
      if (flags & MPP_CLOSE_ON_SIGNAL)
1893
 
        {
1894
 
          multi_close_instance_on_signal (m, mi);
1895
 
          ret = false;
1896
 
        }
1897
 
    }
1898
 
  else
1899
 
    {
1900
 
      /* continue to pend on output? */
1901
 
      multi_set_pending (m, ANY_OUT (&mi->context) ? mi : NULL);
1902
 
 
1903
 
#ifdef MULTI_DEBUG_EVENT_LOOP
1904
 
      printf ("POST %s[%d] to=%d lo=%d/%d w=%d/%d\n",
1905
 
              id(mi),
1906
 
              (int) (mi == m->pending),
1907
 
              mi ? mi->context.c2.to_tun.len : -1,
1908
 
              mi ? mi->context.c2.to_link.len : -1,
1909
 
              (mi && mi->context.c2.fragment) ? mi->context.c2.fragment->outgoing.len : -1,
1910
 
              (int)mi->context.c2.timeval.tv_sec,
1911
 
              (int)mi->context.c2.timeval.tv_usec);
1912
 
#endif
1913
 
    }
1914
 
 
1915
 
  if ((flags & MPP_RECORD_TOUCH) && m->mpp_touched)
1916
 
    *m->mpp_touched = mi;
1917
 
 
1918
 
  return ret;
1919
 
}
1920
 
 
1921
 
/*
1922
 
 * Process packets in the TCP/UDP socket -> TUN/TAP interface direction,
1923
 
 * i.e. client -> server direction.
1924
 
 */
1925
 
bool
1926
 
multi_process_incoming_link (struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags)
1927
 
{
1928
 
  struct gc_arena gc = gc_new ();
1929
 
 
1930
 
  struct context *c;
1931
 
  struct mroute_addr src, dest;
1932
 
  unsigned int mroute_flags;
1933
 
  struct multi_instance *mi;
1934
 
  bool ret = true;
1935
 
 
1936
 
  if (m->pending)
1937
 
    return true;
1938
 
 
1939
 
  if (!instance)
1940
 
    {
1941
 
#ifdef MULTI_DEBUG_EVENT_LOOP
1942
 
      printf ("TCP/UDP -> TUN [%d]\n", BLEN (&m->top.c2.buf));
1943
 
#endif
1944
 
      multi_set_pending (m, multi_get_create_instance_udp (m));
1945
 
    }
1946
 
  else
1947
 
    multi_set_pending (m, instance);
1948
 
 
1949
 
  if (m->pending)
1950
 
    {
1951
 
      set_prefix (m->pending);
1952
 
 
1953
 
      /* get instance context */
1954
 
      c = &m->pending->context;
1955
 
 
1956
 
      if (!instance)
1957
 
        {
1958
 
          /* transfer packet pointer from top-level context buffer to instance */
1959
 
          c->c2.buf = m->top.c2.buf;
1960
 
 
1961
 
          /* transfer from-addr from top-level context buffer to instance */
1962
 
          c->c2.from = m->top.c2.from;
1963
 
        }
1964
 
 
1965
 
      if (BLEN (&c->c2.buf) > 0)
1966
 
        {
1967
 
          /* decrypt in instance context */
1968
 
          process_incoming_link (c);
1969
 
 
1970
 
          if (TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TUN)
1971
 
            {
1972
 
              /* extract packet source and dest addresses */
1973
 
              mroute_flags = mroute_extract_addr_from_packet (&src,
1974
 
                                                              &dest,
1975
 
                                                              NULL,
1976
 
                                                              NULL,
1977
 
                                                              &c->c2.to_tun,
1978
 
                                                              DEV_TYPE_TUN);
1979
 
 
1980
 
              /* drop packet if extract failed */
1981
 
              if (!(mroute_flags & MROUTE_EXTRACT_SUCCEEDED))
1982
 
                {
1983
 
                  c->c2.to_tun.len = 0;
1984
 
                }
1985
 
              /* make sure that source address is associated with this client */
1986
 
              else if (multi_get_instance_by_virtual_addr (m, &src, true) != m->pending)
1987
 
                {
1988
 
                  msg (D_MULTI_DROPPED, "MULTI: bad source address from client [%s], packet dropped",
1989
 
                       mroute_addr_print (&src, &gc));
1990
 
                  c->c2.to_tun.len = 0;
1991
 
                }
1992
 
              /* client-to-client communication enabled? */
1993
 
              else if (m->enable_c2c)
1994
 
                {
1995
 
                  /* multicast? */
1996
 
                  if (mroute_flags & MROUTE_EXTRACT_MCAST)
1997
 
                    {
1998
 
                      /* for now, treat multicast as broadcast */
1999
 
                      multi_bcast (m, &c->c2.to_tun, m->pending, NULL);
2000
 
                    }
2001
 
                  else /* possible client to client routing */
2002
 
                    {
2003
 
                      ASSERT (!(mroute_flags & MROUTE_EXTRACT_BCAST));
2004
 
                      mi = multi_get_instance_by_virtual_addr (m, &dest, true);
2005
 
                  
2006
 
                      /* if dest addr is a known client, route to it */
2007
 
                      if (mi)
2008
 
                        {
2009
 
#ifdef ENABLE_PF
2010
 
                          if (!pf_c2c_test (c, &mi->context, "tun_c2c"))
2011
 
                            {
2012
 
                              msg (D_PF_DROPPED, "PF: client -> client[%s] packet dropped by TUN packet filter",
2013
 
                                   mi_prefix (mi));
2014
 
                            }
2015
 
                          else
2016
 
#endif
2017
 
                            {
2018
 
                              multi_unicast (m, &c->c2.to_tun, mi);
2019
 
                              register_activity (c, BLEN(&c->c2.to_tun));
2020
 
                            }
2021
 
                          c->c2.to_tun.len = 0;
2022
 
                        }
2023
 
                    }
2024
 
                }
2025
 
#ifdef ENABLE_PF
2026
 
              if (c->c2.to_tun.len && !pf_addr_test (c, &dest, "tun_dest_addr"))
2027
 
                {
2028
 
                  msg (D_PF_DROPPED, "PF: client -> addr[%s] packet dropped by TUN packet filter",
2029
 
                       mroute_addr_print_ex (&dest, MAPF_SHOW_ARP, &gc));
2030
 
                  c->c2.to_tun.len = 0;
2031
 
                }
2032
 
#endif
2033
 
            }
2034
 
          else if (TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TAP)
2035
 
            {
2036
 
#ifdef ENABLE_PF
2037
 
              struct mroute_addr edest;
2038
 
              mroute_addr_reset (&edest);
2039
 
#endif
2040
 
              /* extract packet source and dest addresses */
2041
 
              mroute_flags = mroute_extract_addr_from_packet (&src,
2042
 
                                                              &dest,
2043
 
                                                              NULL,
2044
 
#ifdef ENABLE_PF
2045
 
                                                              &edest,
2046
 
#else
2047
 
                                                              NULL,
2048
 
#endif
2049
 
                                                              &c->c2.to_tun,
2050
 
                                                              DEV_TYPE_TAP);
2051
 
 
2052
 
              if (mroute_flags & MROUTE_EXTRACT_SUCCEEDED)
2053
 
                {
2054
 
                  if (multi_learn_addr (m, m->pending, &src, 0) == m->pending)
2055
 
                    {
2056
 
                      /* check for broadcast */
2057
 
                      if (m->enable_c2c)
2058
 
                        {
2059
 
                          if (mroute_flags & (MROUTE_EXTRACT_BCAST|MROUTE_EXTRACT_MCAST))
2060
 
                            {
2061
 
                              multi_bcast (m, &c->c2.to_tun, m->pending, NULL);
2062
 
                            }
2063
 
                          else /* try client-to-client routing */
2064
 
                            {
2065
 
                              mi = multi_get_instance_by_virtual_addr (m, &dest, false);
2066
 
 
2067
 
                              /* if dest addr is a known client, route to it */
2068
 
                              if (mi)
2069
 
                                {
2070
 
#ifdef ENABLE_PF
2071
 
                                  if (!pf_c2c_test (c, &mi->context, "tap_c2c"))
2072
 
                                    {
2073
 
                                      msg (D_PF_DROPPED, "PF: client -> client[%s] packet dropped by TAP packet filter",
2074
 
                                           mi_prefix (mi));
2075
 
                                    }
2076
 
                                  else
2077
 
#endif
2078
 
                                    {
2079
 
                                      multi_unicast (m, &c->c2.to_tun, mi);
2080
 
                                      register_activity (c, BLEN(&c->c2.to_tun));
2081
 
                                    }
2082
 
                                  c->c2.to_tun.len = 0;
2083
 
                                }
2084
 
                            }
2085
 
                        }
2086
 
#ifdef ENABLE_PF
2087
 
                      if (c->c2.to_tun.len && !pf_addr_test (c, &edest, "tap_dest_addr"))
2088
 
                        {
2089
 
                          msg (D_PF_DROPPED, "PF: client -> addr[%s] packet dropped by TAP packet filter",
2090
 
                               mroute_addr_print_ex (&edest, MAPF_SHOW_ARP, &gc));
2091
 
                          c->c2.to_tun.len = 0;
2092
 
                        }
2093
 
#endif
2094
 
                    }
2095
 
                  else
2096
 
                    {
2097
 
                      msg (D_MULTI_DROPPED, "MULTI: bad source address from client [%s], packet dropped",
2098
 
                           mroute_addr_print (&src, &gc));
2099
 
                      c->c2.to_tun.len = 0;
2100
 
                    }
2101
 
                }
2102
 
              else
2103
 
                {
2104
 
                  c->c2.to_tun.len = 0;
2105
 
                }
2106
 
            }
2107
 
        }
2108
 
 
2109
 
      /* postprocess and set wakeup */
2110
 
      ret = multi_process_post (m, m->pending, mpp_flags);
2111
 
 
2112
 
      clear_prefix ();
2113
 
    }
2114
 
 
2115
 
  gc_free (&gc);
2116
 
  return ret;
2117
 
}
2118
 
 
2119
 
/*
2120
 
 * Process packets in the TUN/TAP interface -> TCP/UDP socket direction,
2121
 
 * i.e. server -> client direction.
2122
 
 */
2123
 
bool
2124
 
multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flags)
2125
 
{
2126
 
  struct gc_arena gc = gc_new ();
2127
 
  bool ret = true;
2128
 
 
2129
 
  if (BLEN (&m->top.c2.buf) > 0)
2130
 
    {
2131
 
      unsigned int mroute_flags;
2132
 
      struct mroute_addr src, dest;
2133
 
      const int dev_type = TUNNEL_TYPE (m->top.c1.tuntap);
2134
 
 
2135
 
#ifdef ENABLE_PF
2136
 
      struct mroute_addr esrc, *e1, *e2;
2137
 
      if (dev_type == DEV_TYPE_TUN)
2138
 
        {
2139
 
          e1 = NULL;
2140
 
          e2 = &src;
2141
 
        }
2142
 
      else
2143
 
        {
2144
 
          e1 = e2 = &esrc;
2145
 
          mroute_addr_reset (&esrc);
2146
 
        }
2147
 
#endif
2148
 
 
2149
 
#ifdef MULTI_DEBUG_EVENT_LOOP
2150
 
      printf ("TUN -> TCP/UDP [%d]\n", BLEN (&m->top.c2.buf));
2151
 
#endif
2152
 
 
2153
 
      if (m->pending)
2154
 
        return true;
2155
 
 
2156
 
      /* 
2157
 
       * Route an incoming tun/tap packet to
2158
 
       * the appropriate multi_instance object.
2159
 
       */
2160
 
 
2161
 
      mroute_flags = mroute_extract_addr_from_packet (&src,
2162
 
                                                      &dest,
2163
 
#ifdef ENABLE_PF
2164
 
                                                      e1,
2165
 
#else
2166
 
                                                      NULL,
2167
 
#endif
2168
 
                                                      NULL,
2169
 
                                                      &m->top.c2.buf,
2170
 
                                                      dev_type);
2171
 
 
2172
 
      if (mroute_flags & MROUTE_EXTRACT_SUCCEEDED)
2173
 
        {
2174
 
          struct context *c;
2175
 
 
2176
 
          /* broadcast or multicast dest addr? */
2177
 
          if (mroute_flags & (MROUTE_EXTRACT_BCAST|MROUTE_EXTRACT_MCAST))
2178
 
            {
2179
 
              /* for now, treat multicast as broadcast */
2180
 
#ifdef ENABLE_PF
2181
 
              multi_bcast (m, &m->top.c2.buf, NULL, e2);
2182
 
#else
2183
 
              multi_bcast (m, &m->top.c2.buf, NULL, NULL);
2184
 
#endif
2185
 
            }
2186
 
          else
2187
 
            {
2188
 
              multi_set_pending (m, multi_get_instance_by_virtual_addr (m, &dest, dev_type == DEV_TYPE_TUN));
2189
 
 
2190
 
              if (m->pending)
2191
 
                {
2192
 
                  /* get instance context */
2193
 
                  c = &m->pending->context;
2194
 
                  
2195
 
                  set_prefix (m->pending);
2196
 
 
2197
 
#ifdef ENABLE_PF
2198
 
                  if (!pf_addr_test (c, e2, "tun_tap_src_addr"))
2199
 
                    {
2200
 
                      msg (D_PF_DROPPED, "PF: addr[%s] -> client packet dropped by packet filter",
2201
 
                           mroute_addr_print_ex (&src, MAPF_SHOW_ARP, &gc));
2202
 
                      buf_reset_len (&c->c2.buf);
2203
 
                    }
2204
 
                  else
2205
 
#endif
2206
 
                  {
2207
 
                    if (multi_output_queue_ready (m, m->pending))
2208
 
                      {
2209
 
                        /* transfer packet pointer from top-level context buffer to instance */
2210
 
                        c->c2.buf = m->top.c2.buf;
2211
 
                      }
2212
 
                    else
2213
 
                      {
2214
 
                        /* drop packet */
2215
 
                        msg (D_MULTI_DROPPED, "MULTI: packet dropped due to output saturation (multi_process_incoming_tun)");
2216
 
                        buf_reset_len (&c->c2.buf);
2217
 
                      }
2218
 
                  }
2219
 
              
2220
 
                  /* encrypt in instance context */
2221
 
                  process_incoming_tun (c);
2222
 
 
2223
 
                  /* postprocess and set wakeup */
2224
 
                  ret = multi_process_post (m, m->pending, mpp_flags);
2225
 
 
2226
 
                  clear_prefix ();
2227
 
                }
2228
 
            }
2229
 
        }
2230
 
    }
2231
 
  gc_free (&gc);
2232
 
  return ret;
2233
 
}
2234
 
 
2235
 
/*
2236
 
 * Process a possible client-to-client/bcast/mcast message in the
2237
 
 * queue.
2238
 
 */
2239
 
struct multi_instance *
2240
 
multi_get_queue (struct mbuf_set *ms)
2241
 
{
2242
 
  struct mbuf_item item;
2243
 
 
2244
 
  if (mbuf_extract_item (ms, &item)) /* cleartext IP packet */
2245
 
    {
2246
 
      unsigned int pipv4_flags = PIPV4_PASSTOS;
2247
 
 
2248
 
      set_prefix (item.instance);
2249
 
      item.instance->context.c2.buf = item.buffer->buf;
2250
 
      if (item.buffer->flags & MF_UNICAST) /* --mssfix doesn't make sense for broadcast or multicast */
2251
 
        pipv4_flags |= PIPV4_MSSFIX;
2252
 
      process_ipv4_header (&item.instance->context, pipv4_flags, &item.instance->context.c2.buf);
2253
 
      encrypt_sign (&item.instance->context, true);
2254
 
      mbuf_free_buf (item.buffer);
2255
 
 
2256
 
      dmsg (D_MULTI_DEBUG, "MULTI: C2C/MCAST/BCAST");
2257
 
 
2258
 
      clear_prefix ();
2259
 
      return item.instance;
2260
 
    }
2261
 
  else
2262
 
    {
2263
 
      return NULL;
2264
 
    }
2265
 
}
2266
 
 
2267
 
/*
2268
 
 * Called when an I/O wait times out.  Usually means that a particular
2269
 
 * client instance object needs timer-based service.
2270
 
 */
2271
 
bool
2272
 
multi_process_timeout (struct multi_context *m, const unsigned int mpp_flags)
2273
 
{
2274
 
  bool ret = true;
2275
 
 
2276
 
#ifdef MULTI_DEBUG_EVENT_LOOP
2277
 
  printf ("%s -> TIMEOUT\n", id(m->earliest_wakeup));
2278
 
#endif
2279
 
 
2280
 
  /* instance marked for wakeup? */
2281
 
  if (m->earliest_wakeup)
2282
 
    {
2283
 
      set_prefix (m->earliest_wakeup);
2284
 
      ret = multi_process_post (m, m->earliest_wakeup, mpp_flags);
2285
 
      m->earliest_wakeup = NULL;
2286
 
      clear_prefix ();
2287
 
    }
2288
 
  return ret;
2289
 
}
2290
 
 
2291
 
/*
2292
 
 * Drop a TUN/TAP outgoing packet..
2293
 
 */
2294
 
void
2295
 
multi_process_drop_outgoing_tun (struct multi_context *m, const unsigned int mpp_flags)
2296
 
{
2297
 
  struct multi_instance *mi = m->pending;
2298
 
 
2299
 
  ASSERT (mi);
2300
 
 
2301
 
  set_prefix (mi);
2302
 
 
2303
 
  msg (D_MULTI_ERRORS, "MULTI: Outgoing TUN queue full, dropped packet len=%d",
2304
 
       mi->context.c2.to_tun.len);
2305
 
 
2306
 
  buf_reset (&mi->context.c2.to_tun);
2307
 
 
2308
 
  multi_process_post (m, mi, mpp_flags);
2309
 
  clear_prefix ();
2310
 
}
2311
 
 
2312
 
/*
2313
 
 * Per-client route quota management
2314
 
 */
2315
 
 
2316
 
void
2317
 
route_quota_exceeded (const struct multi_context *m, const struct multi_instance *mi)
2318
 
{
2319
 
  struct gc_arena gc = gc_new ();
2320
 
  msg (D_ROUTE_QUOTA, "MULTI ROUTE: route quota (%d) exceeded for %s (see --max-routes-per-client option)",
2321
 
        mi->context.options.max_routes_per_client,
2322
 
        multi_instance_string (mi, false, &gc));
2323
 
  gc_free (&gc);
2324
 
}
2325
 
 
2326
 
#ifdef ENABLE_DEBUG
2327
 
/*
2328
 
 * Flood clients with random packets
2329
 
 */
2330
 
static void
2331
 
gremlin_flood_clients (struct multi_context *m)
2332
 
{
2333
 
  const int level = GREMLIN_PACKET_FLOOD_LEVEL (m->top.options.gremlin);
2334
 
  if (level)
2335
 
    {
2336
 
      struct gc_arena gc = gc_new ();
2337
 
      struct buffer buf = alloc_buf_gc (BUF_SIZE (&m->top.c2.frame), &gc);
2338
 
      struct packet_flood_parms parm = get_packet_flood_parms (level);
2339
 
      int i;
2340
 
 
2341
 
      ASSERT (buf_init (&buf, FRAME_HEADROOM (&m->top.c2.frame)));
2342
 
      parm.packet_size = min_int (parm.packet_size, MAX_RW_SIZE_TUN (&m->top.c2.frame));
2343
 
 
2344
 
      msg (D_GREMLIN, "GREMLIN_FLOOD_CLIENTS: flooding clients with %d packets of size %d",
2345
 
           parm.n_packets,
2346
 
           parm.packet_size);
2347
 
 
2348
 
      for (i = 0; i < parm.packet_size; ++i)
2349
 
        ASSERT (buf_write_u8 (&buf, get_random () & 0xFF));
2350
 
 
2351
 
      for (i = 0; i < parm.n_packets; ++i)
2352
 
        multi_bcast (m, &buf, NULL, NULL);
2353
 
 
2354
 
      gc_free (&gc);
2355
 
    }
2356
 
}
2357
 
#endif
2358
 
 
2359
 
/*
2360
 
 * Process timers in the top-level context
2361
 
 */
2362
 
void
2363
 
multi_process_per_second_timers_dowork (struct multi_context *m)
2364
 
{
2365
 
  /* possibly reap instances/routes in vhash */
2366
 
  multi_reap_process (m);
2367
 
 
2368
 
  /* possibly print to status log */
2369
 
  if (m->top.c1.status_output)
2370
 
    {
2371
 
      if (status_trigger (m->top.c1.status_output))
2372
 
        multi_print_status (m, m->top.c1.status_output, m->status_file_version);
2373
 
    }
2374
 
 
2375
 
  /* possibly flush ifconfig-pool file */
2376
 
  multi_ifconfig_pool_persist (m, false);
2377
 
 
2378
 
#ifdef ENABLE_DEBUG
2379
 
  gremlin_flood_clients (m);
2380
 
#endif
2381
 
}
2382
 
 
2383
 
void
2384
 
multi_top_init (struct multi_context *m, const struct context *top, const bool alloc_buffers)
2385
 
{
2386
 
  inherit_context_top (&m->top, top);
2387
 
  m->top.c2.buffers = NULL;
2388
 
  if (alloc_buffers)
2389
 
    m->top.c2.buffers = init_context_buffers (&top->c2.frame);
2390
 
}
2391
 
 
2392
 
void
2393
 
multi_top_free (struct multi_context *m)
2394
 
{
2395
 
  close_context (&m->top, -1, CC_GC_FREE);
2396
 
  free_context_buffers (m->top.c2.buffers);
2397
 
}
2398
 
 
2399
 
/*
2400
 
 * Return true if event loop should break,
2401
 
 * false if it should continue.
2402
 
 */
2403
 
bool
2404
 
multi_process_signal (struct multi_context *m)
2405
 
{
2406
 
  if (m->top.sig->signal_received == SIGUSR2)
2407
 
    {
2408
 
      struct status_output *so = status_open (NULL, 0, M_INFO, NULL, 0);
2409
 
      multi_print_status (m, so, m->status_file_version);
2410
 
      status_close (so);
2411
 
      m->top.sig->signal_received = 0;
2412
 
      return false;
2413
 
    }
2414
 
  return true;
2415
 
}
2416
 
 
2417
 
/*
2418
 
 * Called when an instance should be closed due to the
2419
 
 * reception of a soft signal.
2420
 
 */
2421
 
void
2422
 
multi_close_instance_on_signal (struct multi_context *m, struct multi_instance *mi)
2423
 
{
2424
 
  remap_signal (&mi->context);
2425
 
  set_prefix (mi);
2426
 
  print_signal (mi->context.sig, "client-instance", D_MULTI_LOW);
2427
 
  clear_prefix ();
2428
 
  multi_close_instance (m, mi, false);
2429
 
}
2430
 
 
2431
 
static void
2432
 
multi_signal_instance (struct multi_context *m, struct multi_instance *mi, const int sig)
2433
 
{
2434
 
  mi->context.sig->signal_received = sig;
2435
 
  multi_close_instance_on_signal (m, mi);
2436
 
}
2437
 
 
2438
 
/*
2439
 
 * Management subsystem callbacks
2440
 
 */
2441
 
 
2442
 
#ifdef ENABLE_MANAGEMENT
2443
 
 
2444
 
static void
2445
 
management_callback_status (void *arg, const int version, struct status_output *so)
2446
 
{
2447
 
  struct multi_context *m = (struct multi_context *) arg;
2448
 
 
2449
 
  if (!version)
2450
 
    multi_print_status (m, so, m->status_file_version);
2451
 
  else
2452
 
    multi_print_status (m, so, version);
2453
 
}
2454
 
 
2455
 
static int
2456
 
management_callback_n_clients (void *arg)
2457
 
{
2458
 
  struct multi_context *m = (struct multi_context *) arg;
2459
 
  return m->n_clients;
2460
 
}
2461
 
 
2462
 
static int
2463
 
management_callback_kill_by_cn (void *arg, const char *del_cn)
2464
 
{
2465
 
  struct multi_context *m = (struct multi_context *) arg;
2466
 
  struct hash_iterator hi;
2467
 
  struct hash_element *he;
2468
 
  int count = 0;
2469
 
 
2470
 
  hash_iterator_init (m->iter, &hi);
2471
 
  while ((he = hash_iterator_next (&hi)))
2472
 
    {
2473
 
      struct multi_instance *mi = (struct multi_instance *) he->value;
2474
 
      if (!mi->halt)
2475
 
        {
2476
 
          const char *cn = tls_common_name (mi->context.c2.tls_multi, false);
2477
 
          if (cn && !strcmp (cn, del_cn))
2478
 
            {
2479
 
              multi_signal_instance (m, mi, SIGTERM);
2480
 
              ++count;
2481
 
            }
2482
 
        }
2483
 
    }
2484
 
  hash_iterator_free (&hi);
2485
 
  return count;
2486
 
}
2487
 
 
2488
 
static int
2489
 
management_callback_kill_by_addr (void *arg, const in_addr_t addr, const int port)
2490
 
{
2491
 
  struct multi_context *m = (struct multi_context *) arg;
2492
 
  struct hash_iterator hi;
2493
 
  struct hash_element *he;
2494
 
  struct openvpn_sockaddr saddr;
2495
 
  struct mroute_addr maddr;
2496
 
  int count = 0;
2497
 
 
2498
 
  CLEAR (saddr);
2499
 
  saddr.sa.sin_family = AF_INET;
2500
 
  saddr.sa.sin_addr.s_addr = htonl (addr);
2501
 
  saddr.sa.sin_port = htons (port);
2502
 
  if (mroute_extract_openvpn_sockaddr (&maddr, &saddr, true))
2503
 
    {
2504
 
      hash_iterator_init (m->iter, &hi);
2505
 
      while ((he = hash_iterator_next (&hi)))
2506
 
        {
2507
 
          struct multi_instance *mi = (struct multi_instance *) he->value;
2508
 
          if (!mi->halt && mroute_addr_equal (&maddr, &mi->real))
2509
 
            {
2510
 
              multi_signal_instance (m, mi, SIGTERM);
2511
 
              ++count;
2512
 
            }
2513
 
        }
2514
 
      hash_iterator_free (&hi);
2515
 
    }
2516
 
  return count;
2517
 
}
2518
 
 
2519
 
static void
2520
 
management_delete_event (void *arg, event_t event)
2521
 
{
2522
 
  struct multi_context *m = (struct multi_context *) arg;
2523
 
  if (m->mtcp)
2524
 
    multi_tcp_delete_event (m->mtcp, event);
2525
 
}
2526
 
 
2527
 
#endif
2528
 
 
2529
 
#ifdef MANAGEMENT_DEF_AUTH
2530
 
 
2531
 
static struct multi_instance *
2532
 
lookup_by_cid (struct multi_context *m, const unsigned long cid)
2533
 
{
2534
 
  if (m)
2535
 
    {
2536
 
      struct multi_instance *mi = (struct multi_instance *) hash_lookup (m->cid_hash, &cid);
2537
 
      if (mi && !mi->halt)
2538
 
        return mi;
2539
 
    }
2540
 
  return NULL;
2541
 
}
2542
 
 
2543
 
static bool
2544
 
management_kill_by_cid (void *arg, const unsigned long cid)
2545
 
{
2546
 
  struct multi_context *m = (struct multi_context *) arg;
2547
 
  struct multi_instance *mi = lookup_by_cid (m, cid);
2548
 
  if (mi)
2549
 
    {
2550
 
      send_restart (&mi->context); /* was: multi_signal_instance (m, mi, SIGTERM); */
2551
 
      return true;
2552
 
    }
2553
 
  else
2554
 
    return false;
2555
 
}
2556
 
 
2557
 
static bool
2558
 
management_client_auth (void *arg,
2559
 
                        const unsigned long cid,
2560
 
                        const unsigned int mda_key_id,
2561
 
                        const bool auth,
2562
 
                        const char *reason,
2563
 
                        const char *client_reason,
2564
 
                        struct buffer_list *cc_config) /* ownership transferred */
2565
 
{
2566
 
  struct multi_context *m = (struct multi_context *) arg;
2567
 
  struct multi_instance *mi = lookup_by_cid (m, cid);
2568
 
  bool cc_config_owned = true;
2569
 
  bool ret = false;
2570
 
 
2571
 
  if (mi)
2572
 
    {
2573
 
      ret = tls_authenticate_key (mi->context.c2.tls_multi, mda_key_id, auth, client_reason);
2574
 
      if (ret)
2575
 
        {
2576
 
          if (auth)
2577
 
            {
2578
 
              if (!mi->connection_established_flag)
2579
 
                {
2580
 
                  set_cc_config (mi, cc_config);
2581
 
                  cc_config_owned = false;
2582
 
                }
2583
 
            }
2584
 
          else
2585
 
            {
2586
 
              if (reason)
2587
 
                msg (D_MULTI_LOW, "MULTI: connection rejected: %s, CLI:%s", reason, np(client_reason));
2588
 
              if (mi->connection_established_flag)
2589
 
                {
2590
 
                  send_auth_failed (&mi->context, client_reason); /* mid-session reauth failed */
2591
 
                  multi_schedule_context_wakeup(m, mi);
2592
 
                }
2593
 
            }
2594
 
        }
2595
 
    }
2596
 
  if (cc_config_owned && cc_config)
2597
 
    buffer_list_free (cc_config);
2598
 
  return ret;
2599
 
}
2600
 
 
2601
 
static char *
2602
 
management_get_peer_info (void *arg, const unsigned long cid)
2603
 
{
2604
 
  struct multi_context *m = (struct multi_context *) arg;
2605
 
  struct multi_instance *mi = lookup_by_cid (m, cid);
2606
 
  char *ret = NULL;
2607
 
 
2608
 
  if (mi)
2609
 
      ret = tls_get_peer_info (mi->context.c2.tls_multi);
2610
 
 
2611
 
  return ret;
2612
 
}
2613
 
 
2614
 
#endif
2615
 
 
2616
 
#ifdef MANAGEMENT_PF
2617
 
static bool
2618
 
management_client_pf (void *arg,
2619
 
                      const unsigned long cid,
2620
 
                      struct buffer_list *pf_config) /* ownership transferred */
2621
 
{
2622
 
  struct multi_context *m = (struct multi_context *) arg;
2623
 
  struct multi_instance *mi = lookup_by_cid (m, cid);
2624
 
  bool ret = false;
2625
 
 
2626
 
  if (mi && pf_config)
2627
 
    ret = pf_load_from_buffer_list (&mi->context, pf_config);
2628
 
 
2629
 
  if (pf_config)
2630
 
    buffer_list_free (pf_config);
2631
 
  return ret;
2632
 
}
2633
 
#endif
2634
 
 
2635
 
void
2636
 
init_management_callback_multi (struct multi_context *m)
2637
 
{
2638
 
#ifdef ENABLE_MANAGEMENT
2639
 
  if (management)
2640
 
    {
2641
 
      struct management_callback cb;
2642
 
      CLEAR (cb);
2643
 
      cb.arg = m;
2644
 
      cb.flags = MCF_SERVER;
2645
 
      cb.status = management_callback_status;
2646
 
      cb.show_net = management_show_net_callback;
2647
 
      cb.kill_by_cn = management_callback_kill_by_cn;
2648
 
      cb.kill_by_addr = management_callback_kill_by_addr;
2649
 
      cb.delete_event = management_delete_event;
2650
 
      cb.n_clients = management_callback_n_clients;
2651
 
#ifdef MANAGEMENT_DEF_AUTH
2652
 
      cb.kill_by_cid = management_kill_by_cid;
2653
 
      cb.client_auth = management_client_auth;
2654
 
      cb.get_peer_info = management_get_peer_info;
2655
 
#endif
2656
 
#ifdef MANAGEMENT_PF
2657
 
      cb.client_pf = management_client_pf;
2658
 
#endif
2659
 
      management_set_callback (management, &cb);
2660
 
    }
2661
 
#endif
2662
 
}
2663
 
 
2664
 
void
2665
 
uninit_management_callback_multi (struct multi_context *m)
2666
 
{
2667
 
  uninit_management_callback ();
2668
 
}
2669
 
 
2670
 
/*
2671
 
 * Top level event loop.
2672
 
 */
2673
 
void
2674
 
tunnel_server (struct context *top)
2675
 
{
2676
 
  ASSERT (top->options.mode == MODE_SERVER);
2677
 
 
2678
 
  switch (top->options.ce.proto) {
2679
 
  case PROTO_UDPv4:
2680
 
    tunnel_server_udp (top);
2681
 
    break;
2682
 
  case PROTO_TCPv4_SERVER:
2683
 
    tunnel_server_tcp (top);
2684
 
    break;
2685
 
  default:
2686
 
    ASSERT (0);
2687
 
  }
2688
 
}
2689
 
 
2690
 
#else
2691
 
static void dummy(void) {}
2692
 
#endif /* P2MP_SERVER */