2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
4 * This file is part of GnuTLS.
6 * GnuTLS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 # include <sys/socket.h>
25 # include <ws2tcpip.h>
30 #include <sys/select.h>
31 #include <sys/types.h>
43 extern unsigned int verbose
;
44 /* Functions to manipulate sockets
48 socket_recv (const socket_st
* socket
, void *buffer
, int buffer_size
)
56 ret
= gnutls_record_recv (socket
->session
, buffer
, buffer_size
);
57 if (ret
== GNUTLS_E_HEARTBEAT_PING_RECEIVED
)
58 gnutls_heartbeat_pong(socket
->session
, 0);
60 while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_HEARTBEAT_PING_RECEIVED
);
66 ret
= recv (socket
->fd
, buffer
, buffer_size
, 0);
68 while (ret
== -1 && errno
== EINTR
);
74 socket_send (const socket_st
* socket
, const void *buffer
, int buffer_size
)
81 ret
= gnutls_record_send (socket
->session
, buffer
, buffer_size
);
83 while (ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_INTERRUPTED
);
87 ret
= send (socket
->fd
, buffer
, buffer_size
, 0);
89 while (ret
== -1 && errno
== EINTR
);
91 if (ret
> 0 && ret
!= buffer_size
&& verbose
)
93 "*** Only sent %d bytes instead of %d.\n", ret
, buffer_size
);
99 socket_bye (socket_st
* socket
)
105 ret
= gnutls_bye (socket
->session
, GNUTLS_SHUT_WR
);
106 while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
);
108 fprintf (stderr
, "*** gnutls_bye() error: %s\n",
109 gnutls_strerror (ret
));
110 gnutls_deinit (socket
->session
);
111 socket
->session
= NULL
;
114 freeaddrinfo (socket
->addr_info
);
115 socket
->addr_info
= socket
->ptr
= NULL
;
118 free (socket
->hostname
);
119 free (socket
->service
);
121 shutdown (socket
->fd
, SHUT_RDWR
); /* no more receptions */
129 socket_open (socket_st
* hd
, const char *hostname
, const char *service
, int udp
)
131 struct addrinfo hints
, *res
, *ptr
;
133 char buffer
[MAX_BUF
+ 1];
134 char portname
[16] = { 0 };
136 printf ("Resolving '%s'...\n", hostname
);
137 /* get server name */
138 memset (&hints
, 0, sizeof (hints
));
139 hints
.ai_socktype
= udp
? SOCK_DGRAM
: SOCK_STREAM
;
140 if ((err
= getaddrinfo (hostname
, service
, &hints
, &res
)))
142 fprintf (stderr
, "Cannot resolve %s:%s: %s\n", hostname
, service
,
148 for (ptr
= res
; ptr
!= NULL
; ptr
= ptr
->ai_next
)
150 sd
= socket (ptr
->ai_family
, ptr
->ai_socktype
, ptr
->ai_protocol
);
154 if ((err
= getnameinfo (ptr
->ai_addr
, ptr
->ai_addrlen
, buffer
, MAX_BUF
,
155 portname
, sizeof (portname
),
156 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0)
158 fprintf (stderr
, "getnameinfo(): %s\n", gai_strerror (err
));
162 if (hints
.ai_socktype
== SOCK_DGRAM
)
164 #if defined(IP_DONTFRAG)
166 if (setsockopt (sd
, IPPROTO_IP
, IP_DONTFRAG
,
167 (const void *) &yes
, sizeof (yes
)) < 0)
168 perror ("setsockopt(IP_DF) failed");
169 #elif defined(IP_MTU_DISCOVER)
170 int yes
= IP_PMTUDISC_DO
;
171 if (setsockopt(sd
, IPPROTO_IP
, IP_MTU_DISCOVER
,
172 (const void*) &yes
, sizeof (yes
)) < 0)
173 perror ("setsockopt(IP_DF) failed");
178 printf ("Connecting to '%s:%s'...\n", buffer
, portname
);
180 err
= connect (sd
, ptr
->ai_addr
, ptr
->ai_addrlen
);
183 fprintf (stderr
, "Cannot connect to %s:%s: %s\n", buffer
,
184 portname
, strerror (errno
));
195 fprintf (stderr
, "Could not find a supported socket\n");
201 hd
->hostname
= strdup (hostname
);
202 hd
->ip
= strdup (buffer
);
203 hd
->service
= strdup (portname
);
214 WORD wVersionRequested
;
217 wVersionRequested
= MAKEWORD (1, 1);
218 if (WSAStartup (wVersionRequested
, &wsaData
) != 0)
220 perror ("WSA_STARTUP_ERROR");
223 signal (SIGPIPE
, SIG_IGN
);