tlx.c revision eed64e98ce34ec2844d4c68b7e5af30cf962e9c8
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*/
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <libintl.h>
#include <unistd.h>
#include <sys/sysmacros.h>
#include <netconfig.h>
#include <errno.h>
#include "inetd_impl.h"
/*
* RPC functions.
*/
/*
* Returns B_TRUE if the non-address components of the 2 rpc_info_t structures
* are equivalent, else B_FALSE.
*/
{
}
/*
* Determine if we have a configured interface for the specified address
* family. This code is a mirror of libnsl's __can_use_af(). We mirror
* it because we need an exact duplicate of its behavior, yet the
* function isn't exported by libnsl, and this fix is considered short-
* term, so it's not worth exporting it.
*
* We need to duplicate __can_use_af() so we can accurately determine
* when getnetconfigent() returns failure for a v6 netid due to no IPv6
* interfaces being configured: getnetconfigent() returns failure
* if a netid is either 'tcp6' or 'udp6' and __can_use_af() returns 0,
* but it doesn't return a return code to uniquely determine this
* failure. If we don't accurately determine these failures, we could
* output error messages in a case when they weren't justified.
*/
static int
{
int fd;
return (0);
}
/* LINTED ECONST_EXPR */
lifn.lifn_count = 0;
}
return (lifn.lifn_count);
}
static boolean_t
is_v6_netid(const char *netid)
{
}
/*
* Registers with rpcbind the program number with all versions, from low to
* high, with the netid, all specified in 'rpc'. If registration fails,
* returns -1, else 0.
*/
int
{
int ver;
/*
* Check whether getnetconfigent() failed as a result of
* having no IPv6 interfaces configured for a v6 netid, or
* as a result of a 'real' error, and output an appropriate
* message with an appropriate severity.
*/
"Couldn't register netid %s for RPC instance %s "
"because no IPv6 interfaces are plumbed"),
} else {
"Failed to lookup netid '%s' for instance %s: %s"),
}
return (-1);
}
"of RPC service instance %s, netid %s"), ver,
return (-1);
}
}
return (0);
}
/* Unregister all the registrations done by register_rpc_service */
void
{
int ver;
/*
* Don't output an error message if getnetconfigent() fails for
* a v6 netid when an IPv6 interface isn't configured.
*/
"Failed to lookup netid '%s' for instance %s: %s"),
}
return;
}
}
/*
*/
int
tlx_init(void)
{
uu_strerror(uu_error()));
return (-1);
}
return (0);
}
void
tlx_fini(void)
{
if (conn_ind_pool != NULL) {
}
}
/*
* Checks if the contents of the 2 tlx_info_t structures are equivalent.
* If 'isrpc' is false, the address components of the two structures are
* compared for equality as part of this. If the two structures are
* equivalent B_TRUE is returned, else B_FALSE.
*/
{
sizeof (struct sockaddr_storage)) == 0)) &&
}
/*
* Attempts to bind an address to the network fd 'fd'. If 'reqaddr' is non-NULL,
* it attempts to bind to that requested address, else it binds to a kernel
* selected address. In the former case, the function returning success
* doesn't guarantee that the requested address was bound (the caller needs to
* check). If 'retaddr' is non-NULL, the bound address is returned in it. The
* 'qlen' parameter is used to set the connection backlog. If the bind
* succeeds 0 is returned, else -1.
*/
static int
{
}
} else {
}
return (-1);
return (0);
}
static int
{
struct {
char data[256];
} optbuf;
return (-1);
}
return (-1);
}
return (0);
}
/*
* Compare contents of netbuf for equality. Return B_TRUE on a match and
* B_FALSE for mismatch.
*/
static boolean_t
{
}
/*
* 'instance' for non-RPC services, else a kernel chosen address.
* Returns -1 on failure, else 0.
*/
int
{
int fd;
int qlen;
struct sockaddr_storage ss;
return (-1);
}
int on = 1;
/* restrict to IPv6 communications only */
sizeof (on)) == -1) {
return (-1);
}
}
/*
* Negotiate for the returning of the remote uid for loopback
* transports for RPC services. This needs to be done before the
* endpoint is bound using t_bind(), so that any requests to it
* contain the uid.
*/
/*
* Bind the service's address to the endpoint and setup connection
* backlog. In the case of RPC services, we specify a NULL requested
* address and accept what we're given, storing the returned address
* for later RPC binding. In the case of non-RPC services we specify
* the service's associated address.
*/
} else {
}
"for instance %s, proto %s"), fmri,
return (-1);
}
return (fd);
}
/*
* Takes a connection request off 'fd' in the form of a t_call structure
* and returns a pointer to it.
* Returns NULL on failure, else pointer to t_call structure on success.
*/
static struct t_call *
get_new_conind(int fd)
{
/* LINTED E_BAD_PTR_CAST_ALIGN */
return (NULL);
}
return (NULL);
}
return (call);
}
/* Add 'call' to the connection indication queue 'queue'. */
int
{
return (-1);
}
return (0);
}
/*
* Remove and return a pointer to the first call on queue 'queue'. However,
* if the queue is empty returns NULL.
*/
struct t_call *
{
return (NULL);
return (ret);
}
/*
* Handle a TLOOK notification received during a t_accept() call.
* Returns -1 on failure, else 0.
*/
static int
{
int event;
case T_LISTEN: {
debug_msg("process_tlook: T_LISTEN event");
return (-1);
"indication for instance %s"), fmri);
return (-1);
}
break;
}
case T_DISCONNECT: {
/*
* Note: In Solaris 2.X (SunOS 5.X) bundled
* connection-oriented transport drivers
* indications to listening endpoints.
* So this will not be seen with endpoints on Solaris
* bundled transport devices. However, Streams TPI
* allows for this (broken?) behavior and so we account
* for it here because of the possibility of unbundled
* transport drivers causing this.
*/
debug_msg("process_tlook: T_DISCONNECT event");
/* LINTED */
return (-1);
}
return (-1);
}
/*
* Find any queued connection pending that matches this
* disconnect notice and remove from the pending queue.
*/
}
}
break;
}
case -1:
return (-1);
default:
event);
return (-1);
}
return (0);
}
/*
* If it is thwarted by a TLOOK, it is deferred and whatever is on the
* file descriptor, removed after a t_look. (Incoming connect indications
* get queued for later processing and disconnect indications remove a
* a queued connection request if a match found).
* Returns -1 on failure, else 0.
*/
int
struct sockaddr_storage *remote_addr)
{
int fd;
return (-1);
}
int on = 1;
/* restrict to IPv6 communications only */
sizeof (on)) == -1) {
return (-1);
}
}
return (-1);
}
/*
* Get the next connection indication - first try the pending
* queue, then, if none there, get a new one from the file descriptor.
*/
debug_msg("taking con off queue");
return (-1);
}
/*
* Accept the connection indication on the newly created endpoint.
* If we fail, and it's the result of a tlook, queue the indication
* if it isn't already, and go and process the t_look.
*/
/*
* We are first one to have to defer accepting
* and start the pending connections list.
*/
call) == -1) {
"Failed to queue connection "
"indication for instance %s"),
fmri);
return (-1);
}
}
} else { /* non-TLOOK accept failure */
/*
* If we were accepting a queued connection, dequeue
* it.
*/
}
return (-1);
}
/* Copy remote address into address parameter */
/* If we were accepting a queued connection, dequeue it. */
return (fd);
}
/* protocol independent network fd close routine */
void
{
} else {
}
}
/*
* Consume some data from the given endpoint of the given wait-based instance.
*/
void
{
int flag;
} else {
}
}