[go: up one dir, main page]

File: xio-tcp.c

package info (click to toggle)
socat 1.4.3.1-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 2,192 kB
  • ctags: 3,709
  • sloc: ansic: 19,348; sh: 3,435; makefile: 154
file content (160 lines) | stat: -rwxr-xr-x 7,995 bytes parent folder | download
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
/* $Id: xio-tcp.c,v 1.20 2005/08/18 19:52:32 gerhard Exp $ */
/* Copyright Gerhard Rieger 2001-2005 */
/* Published under the GNU General Public License V.2, see file COPYING */

/* this file contains the source for TCP related functions and options */

#include "xiosysincludes.h"
#include "xioopen.h"

#include "xio-listen.h"
#include "xio-ip4.h"
#include "xio-ipapp.h"
#include "xio-tcp.h"

#if WITH_TCP

/****** TCP addresses ******/

#if WITH_IP4
const struct addrdesc addr_tcp4_connect = { "tcp4", 3 /* O_RDWR */, xioopen_ip4app_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, "tcp" HELP(":<host>:<port>") };
#if WITH_LISTEN
const struct addrdesc addr_tcp4_listen  = { "tcp4-listen", 3, xioopen_ip4app_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_TCP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, "tcp" HELP(":<port>") };
#endif
#endif /* WITH_IP4 */

#if WITH_IP6
const struct addrdesc addr_tcp6_connect = { "tcp6",    3, xioopen_ip6app_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, "tcp" HELP(":<host>:<port>") };
#if WITH_LISTEN
const struct addrdesc addr_tcp6_listen  = { "tcp6-listen", 3, xioopen_tcp6_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, "tcp" HELP(":<port>") };
#endif
#endif /* WITH_IP6 */

/****** TCP address options ******/

#ifdef TCP_NODELAY
const struct optdesc opt_tcp_nodelay = { "tcp-nodelay",   "nodelay", OPT_TCP_NODELAY, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT,	OFUNC_SOCKOPT, SOL_TCP, TCP_NODELAY };
#endif
#ifdef TCP_MAXSEG
const struct optdesc opt_tcp_maxseg  = { "tcp-maxseg",    "mss",  OPT_TCP_MAXSEG,  GROUP_IP_TCP, PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_MAXSEG };
const struct optdesc opt_tcp_maxseg_late={"tcp-maxseg-late","mss-late",OPT_TCP_MAXSEG_LATE,GROUP_IP_TCP,PH_CONNECTED,TYPE_INT,OFUNC_SOCKOPT, SOL_TCP, TCP_MAXSEG};
#endif
#ifdef TCP_CORK
const struct optdesc opt_tcp_cork   = { "tcp-cork",     "cork", OPT_TCP_CORK,    GROUP_IP_TCP, PH_PASTSOCKET,    TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_CORK };
#endif
#ifdef TCP_STDURG
const struct optdesc opt_tcp_stdurg = { "tcp-stdurg",   "stdurg", OPT_TCP_STDURG,  GROUP_IP_TCP, PH_PASTSOCKET,    TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_STDURG };
#endif
#ifdef TCP_RFC1323
const struct optdesc opt_tcp_rfc1323= { "tcp-rfc1323",  "rfc1323", OPT_TCP_RFC1323, GROUP_IP_TCP, PH_PASTSOCKET,    TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_RFC1323};
#endif
#ifdef TCP_KEEPIDLE
const struct optdesc opt_tcp_keepidle={ "tcp-keepidle", "keepidle",OPT_TCP_KEEPIDLE,GROUP_IP_TCP, PH_PASTSOCKET,    TYPE_INT, OFUNC_SOCKOPT, SOL_TCP,TCP_KEEPIDLE};
#endif
#ifdef TCP_KEEPINTVL
const struct optdesc opt_tcp_keepintvl={"tcp-keepintvl","keepintvl",OPT_TCP_KEEPINTVL,GROUP_IP_TCP,PH_PASTSOCKET,    TYPE_INT, OFUNC_SOCKOPT, SOL_TCP,TCP_KEEPINTVL};
#endif
#ifdef TCP_KEEPCNT
const struct optdesc opt_tcp_keepcnt= { "tcp-keepcnt",  "keepcnt",  OPT_TCP_KEEPCNT, GROUP_IP_TCP, PH_PASTSOCKET,    TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_KEEPCNT };
#endif
#ifdef TCP_SYNCNT
const struct optdesc opt_tcp_syncnt = { "tcp-syncnt",   "syncnt",   OPT_TCP_SYNCNT,  GROUP_IP_TCP, PH_PASTSOCKET,    TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_SYNCNT };
#endif
#ifdef TCP_LINGER2
const struct optdesc opt_tcp_linger2= { "tcp-linger2",  "linger2",  OPT_TCP_LINGER2, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_LINGER2 };
#endif
#ifdef TCP_DEFER_ACCEPT
const struct optdesc opt_tcp_defer_accept={"tcp-defer-accept","defer-accept",OPT_TCP_DEFER_ACCEPT,GROUP_IP_TCP,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_TCP,TCP_DEFER_ACCEPT };
#endif
#ifdef TCP_WINDOW_CLAMP
const struct optdesc opt_tcp_window_clamp={"tcp-window-clamp","window-clamp",OPT_TCP_WINDOW_CLAMP,GROUP_IP_TCP,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_TCP,TCP_WINDOW_CLAMP };
#endif
#ifdef TCP_INFO
const struct optdesc opt_tcp_info   = { "tcp-info",     "info", OPT_TCP_INFO,    GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_INFO };
#endif
#ifdef TCP_QUICKACK
const struct optdesc opt_tcp_quickack = { "tcp-quickack", "quickack", OPT_TCP_QUICKACK, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_QUICKACK };
#endif
#ifdef TCP_NOOPT
const struct optdesc opt_tcp_noopt  = { "tcp-noopt",   "noopt",  OPT_TCP_NOOPT,  GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT,	OFUNC_SOCKOPT, SOL_TCP, TCP_NOOPT };
#endif
#ifdef TCP_NOPUSH
const struct optdesc opt_tcp_nopush = { "tcp-nopush",  "nopush", OPT_TCP_NOPUSH, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT,	OFUNC_SOCKOPT, SOL_TCP, TCP_NOPUSH };
#endif
#ifdef TCP_MD5SIG
const struct optdesc opt_tcp_md5sig = { "tcp-md5sig",   "md5sig", OPT_TCP_MD5SIG, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_MD5SIG };
#endif
#ifdef TCP_SACK_DISABLE
const struct optdesc opt_tcp_sack_disable = { "tcp-sack-disable", "sack-disable", OPT_TCP_SACK_DISABLE, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_SACK_DISABLE };
#endif
#ifdef TCP_SIGNATURE_ENABLE
const struct optdesc opt_tcp_signature_enable = { "tcp-signature-enable", "signature-enable", OPT_TCP_SIGNATURE_ENABLE, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_SIGNATURE_ENABLE };
#endif
#ifdef TCP_ABORT_THRESHOLD	/* HP-UX */
const struct optdesc opt_tcp_abort_threshold = { "tcp-abort-threshold", "abort-threshold", OPT_TCP_ABORT_THRESHOLD, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_ABORT_THRESHOLD };
#endif
#ifdef TCP_CONN_ABORT_THRESHOLD	/* HP-UX */
const struct optdesc opt_tcp_conn_abort_threshold = { "tcp-conn-abort-threshold", "conn-abort-threshold", OPT_TCP_CONN_ABORT_THRESHOLD, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_CONN_ABORT_THRESHOLD };
#endif
#ifdef TCP_KEEPINIT	/* OSF1 aka Tru64 */
const struct optdesc opt_tcp_keepinit = { "tcp-keepinit", "keepinit", OPT_TCP_KEEPINIT, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_KEEPINIT };
#endif
#ifdef TCP_PAWS	/* OSF1 aka Tru64 */
const struct optdesc opt_tcp_paws = { "tcp-paws", "paws", OPT_TCP_PAWS, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_TCP, TCP_PAWS };
#endif
#ifdef TCP_SACKENA	/* OSF1 aka Tru64 */
const struct optdesc opt_tcp_sackena = { "tcp-sackena", "sackena", OPT_TCP_SACKENA, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_TCP, TCP_SACKENA };
#endif
#ifdef TCP_TSOPTENA	/* OSF1 aka Tru64 */
const struct optdesc opt_tcp_tsoptena = { "tcp-tsoptena", "tsoptena", OPT_TCP_TSOPTENA, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_TCP, TCP_TSOPTENA };
#endif

#if WITH_IP6 && WITH_LISTEN
/* we expect the form: port */
int xioopen_tcp6_listen(char *a1, int xioflags, xiofile_t *fd,
			     unsigned groups, int dummy1, int dummy2,
			     void *dummyp1) {
   char *a2;
   struct opt *opts = NULL, *opts0;
   struct sockaddr_in6 us;
   struct sockaddr_in6 them;
   int needbind = 0;
   int socktype = SOCK_STREAM;
   int result;

   if (a2 = strchr(a1, ',')) {
      *a2++ = '\0';
   }

   /* initialization of local vars */
   socket_in6_init(&us);
   socket_in6_init(&them);

   if (parseopts(a2, groups, &opts) < 0) {
      return STAT_NORETRY;
   }

   /* destination port */
   /*0 us.sin6_port       = htons(strtoul(a1, &a1, 0));*/
   us.sin6_port = parseport(a1, "tcp");

   if (retropt_bind(opts, AF_INET6, "tcp", (struct sockaddr *)&us, 1) >= 0)
      needbind = true;

   applyopts(-1, opts, PH_INIT);
   if (applyopts_single(&fd->stream, opts, PH_INIT) < 0)  return -1;
   retropt_int(opts, OPT_SO_TYPE, &socktype);

   opts0 = copyopts(opts, GROUP_ALL);

   if ((result =
	xioopen_listen(&fd->stream, xioflags,
			(struct sockaddr *)&us, sizeof(struct sockaddr_in6),
		       opts, opts0, PF_INET6, socktype, IPPROTO_TCP))
       != 0)
      return result;
   return 0;
}
#endif /* WITH_IP6 && WITH_LISTEN */

#endif /* WITH_TCP */