summaryrefslogtreecommitdiff
path: root/src/VBox/Devices/Network/slirp/socket.h
blob: d97afd5b19fab8b6e24916d617c238d1900c83ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/* $Id: socket.h $ */
/** @file
 * NAT - socket handling (declarations/defines).
 */

/*
 * Copyright (C) 2006-2012 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 */

/*
 * This code is based on:
 *
 * Copyright (c) 1995 Danny Gasparovski.
 *
 * Please read the file COPYRIGHT for the
 * terms and conditions of the copyright.
 */

/* MINE */

#ifndef _SLIRP_SOCKET_H_
#define _SLIRP_SOCKET_H_

#define SO_EXPIRE 240000
#define SO_EXPIREFAST 10000

/*
 * Our socket structure
 */

struct socket
{
    struct socket   *so_next;
    struct socket   *so_prev;    /* For a linked list of sockets */

#if !defined(RT_OS_WINDOWS)
    int s;                       /* The actual socket */
#else
    union {
            int s;
            HANDLE sh;
    };
    uint64_t so_icmp_id; /* XXX: hack */
    uint64_t so_icmp_seq; /* XXX: hack */
#endif

    /* XXX union these with not-yet-used sbuf params */
    struct mbuf     *so_m;       /* Pointer to the original SYN packet,
                                  * for non-blocking connect()'s, and
                                  * PING reply's */
    struct tcpiphdr *so_ti;      /* Pointer to the original ti within
                                  * so_mconn, for non-blocking connections */
    int             so_urgc;
    struct in_addr  so_faddr;    /* foreign host table entry */
    struct in_addr  so_laddr;    /* local host table entry */
    u_int16_t       so_fport;    /* foreign port */
    u_int16_t       so_lport;    /* local port */
    u_int16_t       so_hlport; /* host local port */
    struct in_addr  so_hladdr;    /* local host addr */

    u_int8_t        so_iptos;    /* Type of service */

    u_char          so_type;     /* Type of socket, UDP or TCP */
    int             so_state;    /* internal state flags SS_*, below */

    struct tcpcb    *so_tcpcb;   /* pointer to TCP protocol control block */
    u_int           so_expire;   /* When the socket will expire */

    int             so_queued;   /* Number of packets queued from this socket */
    int             so_nqueued;  /* Number of packets queued in a row
                                  * Used to determine when to "downgrade" a session
                                  * from fastq to batchq */

    struct sbuf     so_rcv;      /* Receive buffer */
    struct sbuf     so_snd;      /* Send buffer */
#ifndef RT_OS_WINDOWS
    int so_poll_index;
#endif /* !RT_OS_WINDOWS */
    /*
     * FD_CLOSE/POLLHUP event has been occurred on socket
     */
    int so_close;

    void (* so_timeout)(PNATState pData, struct socket *so, void *arg);
    void *so_timeout_arg;

#ifdef VBOX_WITH_NAT_SERVICE
    /* storage of source ether address */
    unsigned char so_ethaddr[6];
#endif
    /* required for port-forwarding */
    struct libalias *so_la;
    /* libalias might attach the socket and we want to notify libalias we're freeing it */
    void *so_pvLnk;
#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
    struct socket *so_cloneOf; /* pointer to master instance */
    int so_cCloneCounter;      /* number of clones */
#endif
    /** These flags (''fUnderPolling'' and ''fShouldBeRemoved'') introduced to
     *  to let polling routine gain control over freeing socket whatever level of
     *  TCP/IP initiated socket releasing.
     *  So polling routine when start processing socket alter it's state to
     *  ''fUnderPolling'' to 1, and clean (set to 0) when it finish.
     *  When polling routine calls functions it should be ensure on return,
     *  whether ''fShouldBeRemoved'' set or not, and depending on state call
     *  ''sofree'' or continue socket processing.
     *  On ''fShouldBeRemoved'' equal to 1, polling routine should call ''sofree'',
     *  clearing ''fUnderPolling'' to do real freeng of the socket and removing from
     *  the queue.
     *  @todo: perhaps, to simplefy the things we need some helper function.
     *  @note: it's used like a bool, I use 'int' to avoid compiler warnings
     *  appearing if [-Wc++-compat] used.
     */
    int fUnderPolling;
    /** This flag used by ''sofree'' function in following manner
     *
     *  fUnderPolling = 1, then we don't remove socket from the queue, just
     *  alter value ''fShouldBeRemoved'' to 1, else we do removal.
     */
    int fShouldBeRemoved;
};

/* this function inform libalias about socket close */
void slirpDeleteLinkSocket(void *pvLnk);


# define SOCKET_LOCK(so) do {} while (0)
# define SOCKET_UNLOCK(so) do {} while (0)
# define SOCKET_LOCK_CREATE(so) do {} while (0)
# define SOCKET_LOCK_DESTROY(so) do {} while (0)

/*
 * Socket state bits. (peer means the host on the Internet,
 * local host means the host on the other end of the modem)
 */
#define SS_NOFDREF              0x001   /* No fd reference */

#define SS_ISFCONNECTING        0x002   /* Socket is connecting to peer (non-blocking connect()'s) */
#define SS_ISFCONNECTED         0x004   /* Socket is connected to peer */
#define SS_FCANTRCVMORE         0x008   /* Socket can't receive more from peer (for half-closes) */
#define SS_FCANTSENDMORE        0x010   /* Socket can't send more to peer (for half-closes) */
/* #define SS_ISFDISCONNECTED   0x020*/ /* Socket has disconnected from peer, in 2MSL state */
#define SS_FWDRAIN              0x040   /* We received a FIN, drain data and set SS_FCANTSENDMORE */

/* #define SS_CTL               0x080 */
#define SS_FACCEPTCONN          0x100   /* Socket is accepting connections from a host on the internet */
#define SS_FACCEPTONCE          0x200   /* If set, the SS_FACCEPTCONN socket will die after one accept */

extern struct socket tcb;

#if defined(DECLARE_IOVEC) && !defined(HAVE_READV)
struct iovec
{
    char *iov_base;
    size_t iov_len;
};
#endif

void so_init (void);
struct socket * solookup (struct socket *, struct in_addr, u_int, struct in_addr, u_int);
struct socket * socreate (void);
void sofree (PNATState, struct socket *);
int soread (PNATState, struct socket *);
void sorecvoob (PNATState, struct socket *);
int sosendoob (struct socket *);
int sowrite (PNATState, struct socket *);
void sorecvfrom (PNATState, struct socket *);
int sosendto (PNATState, struct socket *, struct mbuf *);
struct socket * solisten (PNATState, u_int32_t, u_int, u_int32_t, u_int, int);
void sorwakeup (struct socket *);
void sowwakeup (struct socket *);
void soisfconnecting (register struct socket *);
void soisfconnected (register struct socket *);
void sofcantrcvmore (struct  socket *);
void sofcantsendmore (struct socket *);
void soisfdisconnected (struct socket *);
void sofwdrain (struct socket *);

/**
 * Creates copy of UDP socket with specified addr
 * fBindSocket - in case we want bind a real socket.
 * @return copy of the socket with f_addr equal to u32ForeignAddr
 */
#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
struct socket * soCloneUDPSocketWithForegnAddr(PNATState pData, bool fBindSocket, struct socket *pSo, uint32_t u32ForeignAddr);
struct socket *soLookUpClonedUDPSocket(PNATState pData, const struct socket *pcSo, uint32_t u32ForeignAddress);
#endif

static inline int soIgnorableErrorCode(int iErrorCode)
{
    return (   iErrorCode == EINPROGRESS
            || iErrorCode == EAGAIN
            || iErrorCode == EWOULDBLOCK);
}

#endif /* _SOCKET_H_ */