X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_socket.c;h=e83baf4e709279dee9a452c990fa276eadb073a7;hp=c022585978bd7f0d06ef8b205b7c7e913645f5a0;hb=7ce79a5bfdbcd53ae75f85e94eed665a05b5dea3;hpb=4e321ffafff3a1f31bbbfdcf1b17c0ecbde2121f diff --git a/apps/s_socket.c b/apps/s_socket.c index c022585978..e83baf4e70 100644 --- a/apps/s_socket.c +++ b/apps/s_socket.c @@ -87,16 +87,25 @@ typedef unsigned int u_int; #ifndef OPENSSL_NO_SOCK -static struct hostent *GetHostByName(char *name); -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK) +#include "netdb.h" +#endif + +static struct hostent *GetHostByName(const char *name); +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) static void ssl_sock_cleanup(void); #endif static int ssl_sock_init(void); -static int init_client_ip(int *sock,unsigned char ip[4], int port, int type); +static int init_client_ip(int *sock, const unsigned char ip[4], int port, + int type); static int init_server(int *sock, int port, int type); static int init_server_long(int *sock, int port,char *ip, int type); static int do_accept(int acc_sock, int *sock, char **host); -static int host_ip(char *str, unsigned char ip[4]); +static int host_ip(const char *str, unsigned char ip[4]); +#ifndef NO_SYS_UN_H +static int init_server_unix(int *sock, const char *path); +static int do_accept_unix(int acc_sock, int *sock); +#endif #ifdef OPENSSL_SYS_WIN16 #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ @@ -104,7 +113,7 @@ static int host_ip(char *str, unsigned char ip[4]); #define SOCKET_PROTOCOL IPPROTO_TCP #endif -#ifdef OPENSSL_SYS_NETWARE +#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) static int wsa_init_done=0; #endif @@ -156,7 +165,7 @@ static void ssl_sock_cleanup(void) WSACleanup(); } } -#elif defined(OPENSSL_SYS_NETWARE) +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) static void sock_cleanup(void) { if (wsa_init_done) @@ -199,7 +208,7 @@ static int ssl_sock_init(void) SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopHookProc); #endif /* OPENSSL_SYS_WIN16 */ } -#elif defined(OPENSSL_SYS_NETWARE) +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) WORD wVerReq; WSADATA wsaData; int err; @@ -224,20 +233,18 @@ static int ssl_sock_init(void) return(1); } -int init_client(int *sock, char *host, int port, int type) +int init_client(int *sock, const char *host, int port, int type) { unsigned char ip[4]; - short p=0; + ip[0] = ip[1] = ip[2] = ip[3] = 0; if (!host_ip(host,&(ip[0]))) - { - return(0); - } - if (p != 0) port=p; - return(init_client_ip(sock,ip,port,type)); + return 0; + return init_client_ip(sock,ip,port,type); } -static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) +static int init_client_ip(int *sock, const unsigned char ip[4], int port, + int type) { unsigned long addr; struct sockaddr_in them; @@ -262,26 +269,51 @@ static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) if (s == INVALID_SOCKET) { perror("socket"); return(0); } -#ifndef OPENSSL_SYS_MPE +#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) if (type == SOCK_STREAM) { i=0; i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); - if (i < 0) { perror("keepalive"); return(0); } + if (i < 0) { closesocket(s); perror("keepalive"); return(0); } } #endif if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1) - { close(s); perror("connect"); return(0); } + { closesocket(s); perror("connect"); return(0); } + *sock=s; + return(1); + } + +#ifndef NO_SYS_UN_H +int init_client_unix(int *sock, const char *server) + { + struct sockaddr_un them; + int s; + + if (strlen(server) > (UNIX_PATH_MAX + 1)) return(0); + if (!ssl_sock_init()) return(0); + + s=socket(AF_UNIX, SOCK_STREAM, 0); + if (s == INVALID_SOCKET) { perror("socket"); return(0); } + + memset((char *)&them,0,sizeof(them)); + them.sun_family=AF_UNIX; + strcpy(them.sun_path, server); + + if (connect(s, (struct sockaddr *)&them, sizeof(them)) == -1) + { closesocket(s); perror("connect"); return(0); } *sock=s; return(1); } +#endif -int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) +int do_server(int port, int type, int *ret, + int (*cb)(char *hostname, int s, int stype, unsigned char *context), + unsigned char *context, int naccept) { int sock; char *name = NULL; - int accept_socket; + int accept_socket = 0; int i; if (!init_server(&accept_socket,port,type)) return(0); @@ -295,7 +327,11 @@ int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, uns { if (type==SOCK_STREAM) { +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + if (do_accept(accept_socket,&sock,NULL) == 0) +#else if (do_accept(accept_socket,&sock,&name) == 0) +#endif { SHUTDOWN(accept_socket); return(0); @@ -303,11 +339,13 @@ int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, uns } else sock = accept_socket; - i=(*cb)(name,sock, context); + i=(*cb)(name,sock, type, context); if (name != NULL) OPENSSL_free(name); if (type==SOCK_STREAM) SHUTDOWN2(sock); - if (i < 0) + if (naccept != -1) + naccept--; + if (i < 0 || naccept == 0) { SHUTDOWN2(accept_socket); return(i); @@ -315,11 +353,48 @@ int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, uns } } +#ifndef NO_SYS_UN_H +int do_server_unix(const char *path, int *ret, + int (*cb)(char *hostname, int s, int stype, unsigned char *context), + unsigned char *context, int naccept) + { + int sock; + int accept_socket = 0; + int i; + + if (!init_server_unix(&accept_socket, path)) return(0); + + if (ret != NULL) + *ret=accept_socket; + for (;;) + { + if (do_accept_unix(accept_socket, &sock) == 0) + { + SHUTDOWN(accept_socket); + i = 0; + goto out; + } + i=(*cb)(NULL, sock, 0, context); + SHUTDOWN2(sock); + if (naccept != -1) + naccept--; + if (i < 0 || naccept == 0) + { + SHUTDOWN2(accept_socket); + goto out; + } + } +out: + unlink(path); + return(i); + } +#endif + static int init_server_long(int *sock, int port, char *ip, int type) { int ret=0; struct sockaddr_in server; - int s= -1,i; + int s= -1; if (!ssl_sock_init()) return(0); @@ -358,7 +433,6 @@ static int init_server_long(int *sock, int port, char *ip, int type) } /* Make it 128 for linux */ if (type==SOCK_STREAM && listen(s,128) == -1) goto err; - i=0; *sock=s; ret=1; err: @@ -374,9 +448,53 @@ static int init_server(int *sock, int port, int type) return(init_server_long(sock, port, NULL, type)); } +#ifndef NO_SYS_UN_H +static int init_server_unix(int *sock, const char *path) + { + int ret = 0; + struct sockaddr_un server; + int s = -1; + + if (strlen(path) > (UNIX_PATH_MAX + 1)) return(0); + if (!ssl_sock_init()) return(0); + + s=socket(AF_UNIX, SOCK_STREAM, 0); + if (s == INVALID_SOCKET) goto err; + + memset((char *)&server,0,sizeof(server)); + server.sun_family=AF_UNIX; + strcpy(server.sun_path, path); + + if (bind(s, (struct sockaddr *)&server, sizeof(server)) == -1) + { +#ifndef OPENSSL_SYS_WINDOWS + perror("bind"); +#endif + goto err; + } + /* Make it 128 for linux */ + if (listen(s,128) == -1) + { +#ifndef OPENSSL_SYS_WINDOWS + perror("listen"); +#endif + unlink(path); + goto err; + } + *sock=s; + ret=1; +err: + if ((ret == 0) && (s != -1)) + { + SHUTDOWN(s); + } + return(ret); + } +#endif + static int do_accept(int acc_sock, int *sock, char **host) { - int ret,i; + int ret; struct hostent *h1,*h2; static struct sockaddr_in from; int len; @@ -398,7 +516,8 @@ redoit: ret=accept(acc_sock,(struct sockaddr *)&from,(void *)&len); if (ret == INVALID_SOCKET) { -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) + int i; i=WSAGetLastError(); BIO_printf(bio_err,"accept error %d\n",i); #else @@ -443,6 +562,7 @@ redoit: if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL) { perror("OPENSSL_malloc"); + closesocket(ret); return(0); } BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1); @@ -451,12 +571,13 @@ redoit: if (h2 == NULL) { BIO_printf(bio_err,"gethostbyname failure\n"); + closesocket(ret); return(0); } - i=0; if (h2->h_addrtype != AF_INET) { BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); + closesocket(ret); return(0); } } @@ -465,6 +586,32 @@ end: return(1); } +#ifndef NO_SYS_UN_H +static int do_accept_unix(int acc_sock, int *sock) + { + int ret; + + if (!ssl_sock_init()) return(0); + +redoit: + ret=accept(acc_sock, NULL, NULL); + if (ret == INVALID_SOCKET) + { + if (errno == EINTR) + { + /*check_timeout(); */ + goto redoit; + } + fprintf(stderr,"errno=%d ",errno); + perror("accept"); + return(0); + } + + *sock=ret; + return(1); + } +#endif + int extract_host_port(char *str, char **host_ptr, unsigned char *ip, short *port_ptr) { @@ -490,7 +637,7 @@ err: return(0); } -static int host_ip(char *str, unsigned char ip[4]) +static int host_ip(const char *str, unsigned char ip[4]) { unsigned int in[4]; int i; @@ -536,7 +683,7 @@ err: return(0); } -int extract_port(char *str, short *port_ptr) +int extract_port(const char *str, short *port_ptr) { int i; struct servent *s; @@ -568,7 +715,7 @@ static struct ghbn_cache_st static unsigned long ghbn_hits=0L; static unsigned long ghbn_miss=0L; -static struct hostent *GetHostByName(char *name) +static struct hostent *GetHostByName(const char *name) { struct hostent *ret; int i,lowi=0;