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_connect (const socket_st
* hd
)
133 printf ("Connecting to '%s:%s'...\n", hd
->ip
, hd
->service
);
135 err
= connect (hd
->fd
, hd
->ptr
->ai_addr
, hd
->ptr
->ai_addrlen
);
138 fprintf (stderr
, "Cannot connect to %s:%s: %s\n", hd
->hostname
,
139 hd
->service
, strerror (errno
));
145 socket_open (socket_st
* hd
, const char *hostname
, const char *service
, int udp
)
147 struct addrinfo hints
, *res
, *ptr
;
149 char buffer
[MAX_BUF
+ 1];
150 char portname
[16] = { 0 };
152 printf ("Resolving '%s'...\n", hostname
);
153 /* get server name */
154 memset (&hints
, 0, sizeof (hints
));
155 hints
.ai_socktype
= udp
? SOCK_DGRAM
: SOCK_STREAM
;
156 if ((err
= getaddrinfo (hostname
, service
, &hints
, &res
)))
158 fprintf (stderr
, "Cannot resolve %s:%s: %s\n", hostname
, service
,
164 for (ptr
= res
; ptr
!= NULL
; ptr
= ptr
->ai_next
)
166 sd
= socket (ptr
->ai_family
, ptr
->ai_socktype
, ptr
->ai_protocol
);
170 if ((err
= getnameinfo (ptr
->ai_addr
, ptr
->ai_addrlen
, buffer
, MAX_BUF
,
171 portname
, sizeof (portname
),
172 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0)
174 fprintf (stderr
, "getnameinfo(): %s\n", gai_strerror (err
));
184 fprintf (stderr
, "socket(): %s\n", strerror (errno
));
188 if (hints
.ai_socktype
== SOCK_DGRAM
)
190 #if defined(IP_DONTFRAG)
192 if (setsockopt (sd
, IPPROTO_IP
, IP_DONTFRAG
,
193 (const void *) &yes
, sizeof (yes
)) < 0)
194 perror ("setsockopt(IP_DF) failed");
195 #elif defined(IP_MTU_DISCOVER)
196 int yes
= IP_PMTUDISC_DO
;
197 if (setsockopt(sd
, IPPROTO_IP
, IP_MTU_DISCOVER
,
198 (const void*) &yes
, sizeof (yes
)) < 0)
199 perror ("setsockopt(IP_DF) failed");
205 hd
->hostname
= strdup (hostname
);
206 hd
->ip
= strdup (buffer
);
207 hd
->service
= strdup (portname
);
218 WORD wVersionRequested
;
221 wVersionRequested
= MAKEWORD (1, 1);
222 if (WSAStartup (wVersionRequested
, &wsaData
) != 0)
224 perror ("WSA_STARTUP_ERROR");
227 signal (SIGPIPE
, SIG_IGN
);