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
)
55 ret
= gnutls_record_recv (socket
->session
, buffer
, buffer_size
);
57 while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
);
61 ret
= recv (socket
->fd
, buffer
, buffer_size
, 0);
63 while (ret
== -1 && errno
== EINTR
);
69 socket_send (const socket_st
* socket
, const void *buffer
, int buffer_size
)
76 ret
= gnutls_record_send (socket
->session
, buffer
, buffer_size
);
78 while (ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_INTERRUPTED
);
82 ret
= send (socket
->fd
, buffer
, buffer_size
, 0);
84 while (ret
== -1 && errno
== EINTR
);
86 if (ret
> 0 && ret
!= buffer_size
&& verbose
)
88 "*** Only sent %d bytes instead of %d.\n", ret
, buffer_size
);
94 socket_bye (socket_st
* socket
)
100 ret
= gnutls_bye (socket
->session
, GNUTLS_SHUT_WR
);
101 while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
);
103 fprintf (stderr
, "*** gnutls_bye() error: %s\n",
104 gnutls_strerror (ret
));
105 gnutls_deinit (socket
->session
);
106 socket
->session
= NULL
;
109 freeaddrinfo (socket
->addr_info
);
110 socket
->addr_info
= socket
->ptr
= NULL
;
113 free (socket
->hostname
);
114 free (socket
->service
);
116 shutdown (socket
->fd
, SHUT_RDWR
); /* no more receptions */
124 socket_connect (const socket_st
* hd
)
128 printf ("Connecting to '%s:%s'...\n", hd
->ip
, hd
->service
);
130 err
= connect (hd
->fd
, hd
->ptr
->ai_addr
, hd
->ptr
->ai_addrlen
);
133 fprintf (stderr
, "Cannot connect to %s:%s: %s\n", hd
->hostname
,
134 hd
->service
, strerror (errno
));
140 socket_open (socket_st
* hd
, const char *hostname
, const char *service
, int udp
)
142 struct addrinfo hints
, *res
, *ptr
;
144 char buffer
[MAX_BUF
+ 1];
145 char portname
[16] = { 0 };
147 printf ("Resolving '%s'...\n", hostname
);
148 /* get server name */
149 memset (&hints
, 0, sizeof (hints
));
150 hints
.ai_socktype
= udp
? SOCK_DGRAM
: SOCK_STREAM
;
151 if ((err
= getaddrinfo (hostname
, service
, &hints
, &res
)))
153 fprintf (stderr
, "Cannot resolve %s:%s: %s\n", hostname
, service
,
159 for (ptr
= res
; ptr
!= NULL
; ptr
= ptr
->ai_next
)
161 sd
= socket (ptr
->ai_family
, ptr
->ai_socktype
, ptr
->ai_protocol
);
165 if ((err
= getnameinfo (ptr
->ai_addr
, ptr
->ai_addrlen
, buffer
, MAX_BUF
,
166 portname
, sizeof (portname
),
167 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0)
169 fprintf (stderr
, "getnameinfo(): %s\n", gai_strerror (err
));
179 fprintf (stderr
, "socket(): %s\n", strerror (errno
));
183 if (hints
.ai_socktype
== SOCK_DGRAM
)
185 #if defined(IP_DONTFRAG)
187 if (setsockopt (sd
, IPPROTO_IP
, IP_DONTFRAG
,
188 (const void *) &yes
, sizeof (yes
)) < 0)
189 perror ("setsockopt(IP_DF) failed");
190 #elif defined(IP_MTU_DISCOVER)
191 int yes
= IP_PMTUDISC_DO
;
192 if (setsockopt(sd
, IPPROTO_IP
, IP_MTU_DISCOVER
,
193 (const void*) &yes
, sizeof (yes
)) < 0)
194 perror ("setsockopt(IP_DF) failed");
200 hd
->hostname
= strdup (hostname
);
201 hd
->ip
= strdup (buffer
);
202 hd
->service
= strdup (portname
);
213 WORD wVersionRequested
;
216 wVersionRequested
= MAKEWORD (1, 1);
217 if (WSAStartup (wVersionRequested
, &wsaData
) != 0)
219 perror ("WSA_STARTUP_ERROR");
222 signal (SIGPIPE
, SIG_IGN
);