tls_connect (hostname, service)
const char *hostname, *service;
{
- struct protoent *proto;
- int server, false = 0, family, socktype;
- struct sockaddr *addr;
- struct sockaddr_in sin;
- size_t addrlen; /* socklen_t addrlen */
+ int server, false = 0;
#ifdef HAVE_ADDRINFO
- struct addrinfo *in, hints;
+ struct addrinfo *in, *in0, hints;
#else
struct hostent *host;
struct servent *serv;
+ struct sockaddr_in sin;
#endif
- proto = getprotobyname ("tcp");
- if (!proto)
- return -1;
-
#ifdef HAVE_ADDRINFO
memset (&hints, 0, sizeof (hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = proto->p_proto;
-
- if (getaddrinfo (hostname, service, &hints, &in) < 0)
+ if (getaddrinfo (hostname, service, &hints, &in))
return -1;
- family = in->ai_family;
- socktype = in->ai_socktype;
- addr = in->ai_addr;
- addrlen = in->ai_addrlen;
- freeaddrinfo (in);
+ for (in = in0; in; in = in->ai_next)
+ {
+ server = socket (in->ai_family, in->ai_socktype, in->ai_protocol);
+ if (server < 0)
+ continue;
+ if (connect (server, in->ai_addr, in->ai_addrlen) < 0)
+ {
+ server = -1;
+ continue;
+ }
+ break;
+ }
+
+ freeaddrinfo (in0);
+ if (server < 0)
+ return -1;
#else
memset (&sin, 0, sizeof (sin));
host = gethostbyname (hostname);
if (!host)
return -1;
memcpy (&sin.sin_addr, host->h_addr, host->h_length);
- serv = getservbyname (service, proto->p_name);
+ serv = getservbyname (service, "tcp");
if (serv)
- sin.sin_port = htons (serv->s_port);
+ sin.sin_port = serv->s_port;
else if (isdigit (service[0]))
sin.sin_port = htons (atoi (service));
- family = sin.sin_family = AF_INET;
- socktype = SOCK_STREAM;
- addr = (struct sockaddr *)&sin;
- addrlen = sizeof (sin);
-#endif
-
- server = socket (family, socktype, 0);
+ sin.sin_family = AF_INET;
+ server = socket (sin.sin_family, SOCK_STREAM, 0);
if (server == -1)
return -1;
- setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, (const char *) &false,
- sizeof (false));
-
- if (connect (server, addr, addrlen) < 0)
+ if (connect (server, (struct sockaddr *)&sin, sizeof (sin)) < 0)
{
close (server);
return -1;
}
+#endif
+
+ setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, (const char *) &false,
+ sizeof (false));
return server;
}
"The program to run in a subprocess to open an TLSv1 connection."
:group 'starttls)
+(defcustom starttls-negotiation-by-kill-program nil
+ "Starting starttls negotiation by kill command if non-nil."
+ :group 'starttls)
+
+(defcustom starttls-kill-program "c:\\cygwin\\bin\kill"
+ "External kill command to send SIGALRM to starttls."
+ :group 'starttls)
+
(defcustom starttls-extra-args nil
"Extra arguments to `starttls-program'"
:group 'starttls)
(defun starttls-negotiate (process)
- (signal-process (process-id process) 'SIGALRM))
+ (if starttls-negotiation-by-kill-program
+ (call-process starttls-kill-program nil nil nil
+ "-ALRM" (format "%d" (process-id process)))
+ (signal-process (process-id process) 'SIGALRM)))
(defun starttls-open-stream (name buffer host service)
"Open a TLS connection for a service to a host.