VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/slirp/slirp_state.h@ 57784

Last change on this file since 57784 was 57784, checked in by vboxsync, 9 years ago

NAT: rewrite handling of port-forwarding.

The most interesting part is handling of wildcard guest address
(0.0.0.0) for which we are supposed to guess the real guest IP. For
TCP we delay the decision until new connection come and the we can use
the current guess for each new connection. For UDP things are
trickier. For now we set the current guess as the destination on
first incoming packet, but that doesn't handle changes of the guest
address or outgoing packets. This needs more thought.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.2 KB
Line 
1/** @file
2 * NAT - slirp state/configuration.
3 */
4
5/*
6 * Copyright (C) 2006-2015 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#ifndef ___slirp_state_h
18#define ___slirp_state_h
19
20#include <iprt/req.h>
21#include <iprt/critsect.h>
22
23#define COUNTERS_INIT
24#include "counters.h"
25
26#include "ip_icmp.h"
27#include "dnsproxy/dnsproxy.h"
28
29
30/** Where to start DHCP IP number allocation. */
31#define START_ADDR 15
32
33/** DHCP Lease time. */
34#define LEASE_TIME (24 * 3600)
35
36/*
37 * ARP cache this is naive implementaion of ARP
38 * cache of mapping 4 byte IPv4 address to 6 byte
39 * ethernet one.
40 */
41struct arp_cache_entry
42{
43 uint32_t ip;
44 uint8_t ether[6];
45 LIST_ENTRY(arp_cache_entry) list;
46};
47LIST_HEAD(arp_cache_head, arp_cache_entry);
48
49/** TFTP session entry. */
50struct dns_domain_entry
51{
52 char *dd_pszDomain;
53 LIST_ENTRY(dns_domain_entry) dd_list;
54};
55LIST_HEAD(dns_domain_list_head, dns_domain_entry);
56
57#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
58typedef struct DNSMAPPINGENTRY
59{
60 /** host name to map.
61 * @note If pszCName isn't null pszPattern won't be used (see alias_dns.c for
62 * details).
63 */
64 char *pszCName;
65 /** Pattern (simple) of hostnames to map to the specified IP. */
66 char *pszPattern;
67 /** The IP Address. */
68 uint32_t u32IpAddress;
69 /** List entry. */
70 LIST_ENTRY(DNSMAPPINGENTRY) MapList;
71} DNSMAPPINGENTRY, *PDNSMAPPINGENTRY;
72typedef LIST_HEAD(DNSMAPPINGLISTHEAD, DNSMAPPINGENTRY) DNSMAPPINGLISTHEAD;
73#endif
74
75struct dns_entry
76{
77 struct in_addr de_addr;
78 TAILQ_ENTRY(dns_entry) de_list;
79};
80TAILQ_HEAD(dns_list_head, dns_entry);
81TAILQ_HEAD(if_queue, mbuf);
82
83struct port_forward_rule
84{
85 uint16_t proto;
86 uint16_t host_port;
87 uint16_t guest_port;
88 struct in_addr guest_addr;
89 struct in_addr bind_ip;
90 int activated;
91 struct socket *so;
92 LIST_ENTRY(port_forward_rule) list;
93};
94LIST_HEAD(port_forward_rule_list, port_forward_rule);
95
96
97#ifdef RT_OS_WINDOWS
98struct pong;
99TAILQ_HEAD(pong_tailq, pong);
100#endif
101
102/* forward declaration */
103struct proto_handler;
104
105/** Main state/configuration structure for slirp NAT. */
106typedef struct NATState
107{
108#define PROFILE_COUNTER(name, dsc) STAMPROFILE Stat ## name
109#define COUNTING_COUNTER(name, dsc) STAMCOUNTER Stat ## name
110#include "counters.h"
111 /* Stuff from boot.c */
112 void *pbootp_clients;
113 const char *bootp_filename;
114 /* Stuff from if.c */
115 int if_mtu, if_mru;
116 int if_comp;
117 int if_maxlinkhdr;
118 int if_queued;
119 int if_thresh;
120 /* Stuff from icmp.c */
121 struct icmpstat_t icmpstat;
122 /* Stuff from ip_input.c */
123 struct ipstat_t ipstat;
124 struct ipqhead ipq[IPREASS_NHASH];
125 int maxnipq; /* Administrative limit on # of reass queues*/
126 int maxfragsperpacket; /* Maximum number of IPv4 fragments allowed per packet */
127 int nipq; /* total number of reass queues */
128 uint16_t ip_currid;
129 /* Stuff from mbuf.c */
130 /* Stuff from slirp.c */
131 void *pvUser;
132 uint32_t curtime;
133 uint32_t time_fasttimo;
134 uint32_t last_slowtimo;
135 bool do_slowtimo;
136 bool link_up;
137 struct timeval tt;
138 struct in_addr our_addr;
139 struct in_addr alias_addr;
140 struct in_addr special_addr;
141 struct in_addr guest_addr_guess;
142
143 int tcp_rcvspace;
144 int tcp_sndspace;
145 int socket_rcv;
146 int socket_snd;
147 int soMaxConn;
148#ifdef RT_OS_WINDOWS
149 ULONG (WINAPI * pfGetAdaptersAddresses)(ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
150#endif
151 struct dns_list_head pDnsList;
152 struct dns_domain_list_head pDomainList;
153 uint32_t dnsgen; /* XXX: merge with dnsLastUpdate? */
154 struct in_addr tftp_server;
155 struct in_addr loopback_addr;
156 uint32_t dnsLastUpdate;
157 uint32_t netmask;
158 uint8_t client_ethaddr[6];
159 const uint8_t *slirp_ethaddr;
160 char slirp_hostname[33];
161 bool fPassDomain;
162 struct in_addr bindIP;
163 /* Stuff from tcp_input.c */
164 struct socket tcb;
165
166 struct socket *tcp_last_so;
167 tcp_seq tcp_iss;
168 /* Stuff from tcp_timer.c */
169 struct tcpstat_t tcpstat;
170 uint32_t tcp_now;
171 int tcp_reass_qsize;
172 int tcp_reass_maxqlen;
173 int tcp_reass_maxseg;
174 int tcp_reass_overflows;
175 /* Stuff from tftp.c */
176 void *pvTftpSessions;
177 int cTftpSession;
178 const char *tftp_prefix;
179 /* Stuff from udp.c */
180 struct udpstat_t udpstat;
181 struct socket udb;
182 struct socket *udp_last_so;
183
184# ifndef RT_OS_WINDOWS
185 /* counter of sockets needed for allocation enough room to
186 * process sockets with poll/epoll
187 *
188 * NSOCK_INC/DEC should be injected before every
189 * operation on socket queue (tcb, udb)
190 */
191 int nsock;
192# define NSOCK_INC() do {pData->nsock++;} while (0)
193# define NSOCK_DEC() do {pData->nsock--;} while (0)
194# define NSOCK_INC_EX(ex) do {ex->pData->nsock++;} while (0)
195# define NSOCK_DEC_EX(ex) do {ex->pData->nsock--;} while (0)
196# else
197# define NSOCK_INC() do {} while (0)
198# define NSOCK_DEC() do {} while (0)
199# define NSOCK_INC_EX(ex) do {} while (0)
200# define NSOCK_DEC_EX(ex) do {} while (0)
201# endif
202
203 struct socket icmp_socket;
204# if !defined(RT_OS_WINDOWS)
205 struct icmp_storage icmp_msg_head;
206 int cIcmpCacheSize;
207 int iIcmpCacheLimit;
208# else
209 struct pong_tailq pongs_expected;
210 struct pong_tailq pongs_received;
211 size_t cbIcmpPending;
212# endif
213
214#if defined(RT_OS_WINDOWS)
215# define VBOX_SOCKET_EVENT (pData->phEvents[VBOX_SOCKET_EVENT_INDEX])
216 HANDLE phEvents[VBOX_EVENT_COUNT];
217#endif
218#ifdef zone_mbuf
219# undef zone_mbuf
220#endif
221 uma_zone_t zone_mbuf;
222#ifdef zone_clust
223# undef zone_clust
224#endif
225 uma_zone_t zone_clust;
226#ifdef zone_pack
227# undef zone_pack
228#endif
229 uma_zone_t zone_pack;
230#ifdef zone_jumbop
231# undef zone_jumbop
232#endif
233 uma_zone_t zone_jumbop;
234#ifdef zone_jumbo9
235# undef zone_jumbo9
236#endif
237 uma_zone_t zone_jumbo9;
238#ifdef zone_jumbo16
239# undef zone_jumbo16
240#endif
241 uma_zone_t zone_jumbo16;
242#ifdef zone_ext_refcnt
243# undef zone_ext_refcnt
244 int nmbclusters; /* limits number of mbuf clusters */
245 int nmbjumbop; /* limits number of page size jumbo clusters */
246 int nmbjumbo9; /* limits number of 9k jumbo clusters */
247 int nmbjumbo16; /* limits number of 16k jumbo clusters */
248 struct mbstat mbstat;
249#endif
250 uma_zone_t zone_ext_refcnt;
251 /**
252 * in (r89055) using of this behaviour has been changed and mean that Slirp
253 * can't parse hosts strucutures/files to provide to guest host name-resolving
254 * configuration, instead Slirp provides .{interface-number + 1}.3 as a nameserver
255 * and proxies DNS queiries to Host's Name Resolver API.
256 */
257 bool fUseHostResolver;
258 /**
259 * Flag whether using the host resolver mode is permanent
260 * because the user configured it that way.
261 */
262 bool fUseHostResolverPermanent;
263 /* from dnsproxy/dnsproxy.h*/
264 unsigned int authoritative_port;
265 unsigned int authoritative_timeout;
266 unsigned int recursive_port;
267 unsigned int recursive_timeout;
268 unsigned int stats_timeout;
269 unsigned int port;
270
271 unsigned long active_queries;
272 unsigned long all_queries;
273 unsigned long authoritative_queries;
274 unsigned long recursive_queries;
275 unsigned long removed_queries;
276 unsigned long dropped_queries;
277 unsigned long answered_queries;
278 unsigned long dropped_answers;
279 unsigned long late_answers;
280 unsigned long hash_collisions;
281 /*dnsproxy/dnsproxy.c*/
282 unsigned short queryid;
283 struct sockaddr_in authoritative_addr;
284 struct sockaddr_in recursive_addr;
285 int sock_query;
286 int sock_answer;
287 /* dnsproxy/hash.c */
288#define HASHSIZE 10
289#define HASH(id) (id & ((1 << HASHSIZE) - 1))
290 struct request *request_hash[1 << HASHSIZE];
291 /* this field control behaviour of DHCP server */
292 bool fUseDnsProxy;
293
294 LIST_HEAD(RT_NOTHING, libalias) instancehead;
295 int i32AliasMode;
296 struct libalias *proxy_alias;
297 LIST_HEAD(handler_chain, proto_handler) handler_chain;
298 /** Critical R/W section to protect the handler chain list. */
299 RTCRITSECTRW CsRwHandlerChain;
300 struct port_forward_rule_list port_forward_rule_head;
301 struct arp_cache_head arp_cache;
302 /* libalis modules' handlers*/
303 struct proto_handler *ftp_module;
304 struct proto_handler *nbt_module;
305 struct proto_handler *dns_module;
306#ifdef VBOX_WITH_NAT_SEND2HOME
307 /* array of home addresses */
308 struct sockaddr_in *pInSockAddrHomeAddress;
309 /* size of pInSockAddrHomeAddress in elements */
310 int cInHomeAddressSize;
311#endif
312#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
313 DNSMAPPINGLISTHEAD DNSMapHead;
314#endif
315} NATState;
316
317
318/** Default IP time to live. */
319#define ip_defttl IPDEFTTL
320
321/** Number of permanent buffers in mbuf. */
322#define mbuf_thresh 30
323
324/** Use a fixed time before sending keepalive. */
325#define tcp_keepidle TCPTV_KEEP_IDLE
326
327/** Use a fixed interval between keepalive. */
328#define tcp_keepintvl TCPTV_KEEPINTVL
329
330/** Maximum idle time before timing out a connection. */
331#define tcp_maxidle (TCPTV_KEEPCNT * tcp_keepintvl)
332
333/** Default TCP socket options. */
334#define so_options DO_KEEPALIVE
335
336/** Default TCP MSS value. */
337#define tcp_mssdflt TCP_MSS
338
339/** Default TCP round trip time. */
340#define tcp_rttdflt (TCPTV_SRTTDFLT / PR_SLOWHZ)
341
342/** Enable RFC1323 performance enhancements.
343 * @todo check if it really works, it was turned off before. */
344#define tcp_do_rfc1323 1
345
346/** TCP receive buffer size. */
347#define tcp_rcvspace pData->tcp_rcvspace
348
349/** TCP receive buffer size. */
350#define tcp_sndspace pData->tcp_sndspace
351
352/* TCP duplicate ACK retransmit threshold. */
353#define tcprexmtthresh 3
354
355
356#define bootp_filename pData->bootp_filename
357
358#define if_mtu pData->if_mtu
359#define if_mru pData->if_mru
360#define if_comp pData->if_comp
361#define if_maxlinkhdr pData->if_maxlinkhdr
362#define if_queued pData->if_queued
363#define if_thresh pData->if_thresh
364
365#define icmpstat pData->icmpstat
366
367#define ipstat pData->ipstat
368#define ipq pData->ipq
369#define ip_currid pData->ip_currid
370
371#define mbuf_alloced pData->mbuf_alloced
372#define mbuf_max pData->mbuf_max
373#define msize pData->msize
374#define m_freelist pData->m_freelist
375#define m_usedlist pData->m_usedlist
376
377#define curtime pData->curtime
378#define time_fasttimo pData->time_fasttimo
379#define last_slowtimo pData->last_slowtimo
380#define do_slowtimo pData->do_slowtimo
381#define link_up pData->link_up
382#define cUsers pData->cUsers
383#define tt pData->tt
384#define our_addr pData->our_addr
385#ifndef VBOX_SLIRP_ALIAS
386# define alias_addr pData->alias_addr
387#else
388# define handler_chain pData->handler_chain
389#endif
390#define dns_addr pData->dns_addr
391#define loopback_addr pData->loopback_addr
392#define client_ethaddr pData->client_ethaddr
393#define slirp_hostname pData->slirp_hostname
394
395#define tcb pData->tcb
396#define tcp_last_so pData->tcp_last_so
397#define tcp_iss pData->tcp_iss
398
399#define tcpstat pData->tcpstat
400#define tcp_now pData->tcp_now
401
402#define tftp_prefix pData->tftp_prefix
403
404#define udpstat pData->udpstat
405#define udb pData->udb
406#define udp_last_so pData->udp_last_so
407
408#define maxfragsperpacket pData->maxfragsperpacket
409#define maxnipq pData->maxnipq
410#define nipq pData->nipq
411
412#define tcp_reass_qsize pData->tcp_reass_qsize
413#define tcp_reass_maxqlen pData->tcp_reass_maxqlen
414#define tcp_reass_maxseg pData->tcp_reass_maxseg
415#define tcp_reass_overflows pData->tcp_reass_overflows
416
417#define queue_tcp_label tcb
418#define queue_udp_label udb
419#define VBOX_X2(x) x
420#define VBOX_X(x) VBOX_X2(x)
421
422#if 1
423
424# define QSOCKET_LOCK(queue) do {} while (0)
425# define QSOCKET_UNLOCK(queue) do {} while (0)
426# define QSOCKET_LOCK_CREATE(queue) do {} while (0)
427# define QSOCKET_LOCK_DESTROY(queue) do {} while (0)
428# define QSOCKET_FOREACH(so, sonext, label) \
429 for ((so) = VBOX_X2(queue_ ## label ## _label).so_next; \
430 (so) != &(VBOX_X2(queue_ ## label ## _label)); \
431 (so) = (sonext)) \
432 { \
433 (sonext) = (so)->so_next; \
434 Log5(("%s:%d Processing so:%R[natsock]\n", RT_GCC_EXTENSION __FUNCTION__, __LINE__, (so)));
435# define CONTINUE(label) continue
436# define CONTINUE_NO_UNLOCK(label) continue
437# define LOOP_LABEL(label, so, sonext) /* empty*/
438# define DO_TCP_OUTPUT(data, sotcb) tcp_output((data), (sotcb))
439# define DO_TCP_INPUT(data, mbuf, size, so) tcp_input((data), (mbuf), (size), (so))
440# define DO_TCP_CONNECT(data, so) tcp_connect((data), (so))
441# define DO_SOREAD(ret, data, so, ifclose) \
442 do { \
443 (ret) = soread((data), (so), (ifclose)); \
444 } while(0)
445# define DO_SOWRITE(ret, data, so) \
446 do { \
447 (ret) = sowrite((data), (so)); \
448 } while(0)
449# define DO_SORECFROM(data, so) sorecvfrom((data), (so))
450# define SOLOOKUP(so, label, src, sport, dst, dport) \
451 do { \
452 (so) = solookup(&VBOX_X2(queue_ ## label ## _label), (src), (sport), (dst), (dport)); \
453 } while (0)
454# define DO_UDP_DETACH(data, so, ignored) udp_detach((data), (so))
455
456#endif
457
458#define TCP_OUTPUT(data, sotcb) DO_TCP_OUTPUT((data), (sotcb))
459#define TCP_INPUT(data, mbuf, size, so) DO_TCP_INPUT((data), (mbuf), (size), (so))
460#define TCP_CONNECT(data, so) DO_TCP_CONNECT((data), (so))
461#define SOREAD(ret, data, so, ifclose) DO_SOREAD((ret), (data), (so), (ifclose))
462#define SOWRITE(ret, data, so) DO_SOWRITE((ret), (data), (so))
463#define SORECVFROM(data, so) DO_SORECFROM((data), (so))
464#define UDP_DETACH(data, so, so_next) DO_UDP_DETACH((data), (so), (so_next))
465
466/* dnsproxy/dnsproxy.c */
467#define authoritative_port pData->authoritative_port
468#define authoritative_timeout pData->authoritative_timeout
469#define recursive_port pData->recursive_port
470#define recursive_timeout pData->recursive_timeout
471#define stats_timeout pData->stats_timeout
472/* dnsproxy/hash.c */
473#define dns_port pData->port
474#define request_hash pData->request_hash
475#define hash_collisions pData->hash_collisions
476#define active_queries pData->active_queries
477#define all_queries pData->all_queries
478#define authoritative_queries pData->authoritative_queries
479#define recursive_queries pData->recursive_queries
480#define removed_queries pData->removed_queries
481#define dropped_queries pData->dropped_queries
482#define answered_queries pData->answered_queries
483#define dropped_answers pData->dropped_answers
484#define late_answers pData->late_answers
485
486/* dnsproxy/dnsproxy.c */
487#define queryid pData->queryid
488#define authoritative_addr pData->authoritative_addr
489#define recursive_addr pData->recursive_addr
490#define sock_query pData->sock_query
491#define sock_answer pData->sock_answer
492
493#define instancehead pData->instancehead
494
495#define nmbclusters pData->nmbclusters
496#define nmbjumbop pData->nmbjumbop
497#define nmbjumbo9 pData->nmbjumbo9
498#define nmbjumbo16 pData->nmbjumbo16
499#define mbstat pData->mbstat
500#include "ext.h"
501#undef zone_mbuf
502#undef zone_clust
503#undef zone_pack
504#undef zone_jumbop
505#undef zone_jumbo9
506#undef zone_jumbo16
507#undef zone_ext_refcnt
508static inline uma_zone_t slirp_zone_pack(PNATState pData)
509{
510 return pData->zone_pack;
511}
512static inline uma_zone_t slirp_zone_jumbop(PNATState pData)
513{
514 return pData->zone_jumbop;
515}
516static inline uma_zone_t slirp_zone_jumbo9(PNATState pData)
517{
518 return pData->zone_jumbo9;
519}
520static inline uma_zone_t slirp_zone_jumbo16(PNATState pData)
521{
522 return pData->zone_jumbo16;
523}
524static inline uma_zone_t slirp_zone_ext_refcnt(PNATState pData)
525{
526 return pData->zone_ext_refcnt;
527}
528static inline uma_zone_t slirp_zone_mbuf(PNATState pData)
529{
530 return pData->zone_mbuf;
531}
532static inline uma_zone_t slirp_zone_clust(PNATState pData)
533{
534 return pData->zone_clust;
535}
536#ifndef VBOX_SLIRP_BSD
537# define m_adj(m, len) m_adj(pData, (m), (len))
538#endif
539
540#endif /* !___slirp_state_h */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette