/** BEGIN COPYRIGHT BLOCK * Copyright 2001 Sun Microsystems, Inc. * Portions copyright 1999, 2001-2003 Netscape Communications Corporation. * All rights reserved. * END COPYRIGHT BLOCK **/ /* * net.c: sockets abstraction and DNS related things * * Note: sockets created with net_socket are placed in non-blocking mode, * however this API simulates that the calls are blocking. * * Rob McCool */ #include "netsite.h" #include "prio.h" #include "private/pprio.h" #include #include /* Removed for ns security integration #include "sslio/sslio.h" */ #include "net.h" #include "util.h" #include "daemon.h" /* child_exit */ #include "ereport.h" /* error reporting */ #include #ifdef XP_UNIX #include /* inet_ntoa */ #include /* hostent stuff */ #ifdef NEED_GHN_PROTO extern "C" int gethostname (char *name, size_t namelen); #endif #endif /* XP_UNIX */ #ifdef LINUX #include /* ioctl */ #endif extern "C" { #include "ssl.h" } #if defined(OSF1) #include #endif #include "base/systems.h" #include "base/dbtbase.h" #if defined(OSF1) #include #endif #ifdef IRIX #include /* fd_zero uses bzero */ #endif #include "netio.h" net_io_t net_io_functions; /* removed for ns security integration #include "xp_error.h" */ #include "libadmin/libadmin.h" int net_enabledns = 1; int net_enableAsyncDNS = 0; int net_listenqsize = DAEMON_LISTEN_SIZE; unsigned int NET_BUFFERSIZE = NET_DEFAULT_BUFFERSIZE; unsigned int NET_READ_TIMEOUT = NET_DEFAULT_READ_TIMEOUT; unsigned int NET_WRITE_TIMEOUT = NET_DEFAULT_WRITE_TIMEOUT; unsigned int SSL_HANDSHAKE_TIMEOUT = SSL_DEFAULT_HANDSHAKE_TIMEOUT; /* ------------------------------ net_init -------------------------------- */ NSAPI_PUBLIC int net_init(int security_on) { return 0; } /* ------------------------------ net_socket ------------------------------ */ NSAPI_PUBLIC SYS_NETFD net_socket(int domain, int type, int protocol) { SYS_NETFD sock; SYS_NETFD prsock; if (security_active) { if (protocol == IPPROTO_TCP) prsock = PR_NewTCPSocket(); else prsock = PR_NewUDPSocket(); if(prsock) sock = SSL_ImportFD(NULL, prsock); else sock = NULL; } else { if (protocol == IPPROTO_TCP) sock = PR_NewTCPSocket(); else sock = PR_NewUDPSocket(); } if (sock == NULL) return (SYS_NETFD)SYS_NET_ERRORFD; return sock; } /* ---------------------------- net_getsockopt ---------------------------- */ NSAPI_PUBLIC int net_getsockopt(SYS_NETFD s, int level, int optname, void *optval, int *optlen) { return getsockopt(PR_FileDesc2NativeHandle(s), level, optname, (char *)optval, (TCPLEN_T *)optlen); } /* ---------------------------- net_setsockopt ---------------------------- */ NSAPI_PUBLIC int net_setsockopt(SYS_NETFD s, int level, int optname, const void *optval, int optlen) { return setsockopt(PR_FileDesc2NativeHandle(s), level, optname, (const char *)optval, optlen); } /* ------------------------------ net_listen ------------------------------ */ NSAPI_PUBLIC int net_listen(SYS_NETFD s, int backlog) { return PR_Listen(s, backlog)==PR_FAILURE?IO_ERROR:0; } /* ------------------------- net_create_listener -------------------------- */ NSAPI_PUBLIC SYS_NETFD net_create_listener(char *ipstr, int port) { SYS_NETFD sd; /* struct sockaddr_in sa_server; */ PRNetAddr sa_server; PRStatus status; PRInt32 flags; if ((sd = net_socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == SYS_NET_ERRORFD) { return SYS_NET_ERRORFD; } #ifdef SOLARIS /* * unset NONBLOCK flag; */ /* Have no idea why Solaris want to unset NONBLOCK flag when it should be in NON-BLOCK mode, and new NSPR20 does not give file descriptor back, so the code are removed --- yjh flags = fcntl(sd->osfd, F_GETFL, 0); fcntl(sd->osfd, F_SETFL, flags & ~O_NONBLOCK); */ #endif /* Convert to NSPR21 for ns security integration ZERO((char *) &sa_server, sizeof(sa_server)); sa_server.sin_family=AF_INET; sa_server.sin_addr.s_addr = (ipstr ? inet_addr(ipstr) : htonl(INADDR_ANY)); sa_server.sin_port=htons(port); if(net_bind(sd, (struct sockaddr *) &sa_server,sizeof(sa_server)) < 0) { return SYS_NET_ERRORFD; } net_listen(sd, net_listenqsize); */ if (ipstr) { status = PR_InitializeNetAddr(PR_IpAddrNull, port, &sa_server); if (status == PR_SUCCESS) sa_server.inet.ip = inet_addr(ipstr); else return SYS_NET_ERRORFD; } else { status = PR_InitializeNetAddr(PR_IpAddrAny, port, &sa_server); if (status == PR_FAILURE) return SYS_NET_ERRORFD; } status = PR_Bind(sd, &sa_server); if (status == PR_FAILURE) return SYS_NET_ERRORFD; status = PR_Listen(sd, net_listenqsize); if (status == PR_FAILURE) return SYS_NET_ERRORFD; return sd; } /* ------------------------------ net_select ------------------------------ */ /* NSAPI_PUBLIC int net_select(int nfds, fd_set *r, fd_set *w, fd_set *e, struct timeval *timeout) { PR_fd_set rd, wr, ex; int index; int rv; if (nfds > (64*1024)) return -1; PR_FD_ZERO(&rd); PR_FD_ZERO(&wr); PR_FD_ZERO(&ex); for (index=0; indextv_sec)); if (rv > 0) { FD_ZERO(r); FD_ZERO(w); FD_ZERO(e); for (index=0; index #else /* WIN32 */ #define MAXHOSTNAMELEN 255 #endif /* XP_UNIX */ /* Defined in dns.c */ char *net_find_fqdn(PRHostEnt *p); NSAPI_PUBLIC char *util_hostname(void) { char str[MAXHOSTNAMELEN]; PRHostEnt hent; char buf[PR_NETDB_BUF_SIZE]; PRStatus err; gethostname(str, MAXHOSTNAMELEN); err = PR_GetHostByName( str, buf, PR_NETDB_BUF_SIZE, &hent); if (err == PR_FAILURE) return NULL; return net_find_fqdn(&hent); }