blob: 40429b4730713cdc472143760da173051fefbd18 [file] [log] [blame]
/* This is a central clearing house for RPC definitions. Nothing
should included anything related to RPC except this file */
#ifndef GSH_RPC_H
#define GSH_RPC_H
#include "config.h"
#include <stdbool.h>
/* Ganesha project has abstract_atomic.h file and tirpc also has a
* similar header with the same name. We want to include ganesha
* project's header here, so include it here before including any
* RPC headers.
*/
#include "abstract_atomic.h"
#include <rpc/xdr_inline.h>
#include <rpc/rpc.h>
#include <rpc/svc.h>
#include <rpc/clnt.h>
#ifdef _HAVE_GSSAPI
#include <rpc/auth_gss.h>
#endif
#include <rpc/svc_auth.h>
#include <rpc/svc_rqst.h>
#include <rpc/rpc_dplx.h>
#include <rpc/rpc_msg.h>
#include <rpc/gss_internal.h> /* XXX */
#include "common_utils.h"
#include "abstract_mem.h"
#include "gsh_list.h"
#include "log.h"
#include "fridgethr.h"
#define NFS_LOOKAHEAD_NONE 0x0000
#define NFS_LOOKAHEAD_MOUNT 0x0001
#define NFS_LOOKAHEAD_OPEN 0x0002
#define NFS_LOOKAHEAD_CLOSE 0x0004
#define NFS_LOOKAHEAD_READ 0x0008
#define NFS_LOOKAHEAD_WRITE 0x0010
#define NFS_LOOKAHEAD_COMMIT 0x0020
#define NFS_LOOKAHEAD_CREATE 0x0040
#define NFS_LOOKAHEAD_REMOVE 0x0080
#define NFS_LOOKAHEAD_RENAME 0x0100
#define NFS_LOOKAHEAD_LOCK 0x0200 /* !_U types */
#define NFS_LOOKAHEAD_READDIR 0x0400
#define NFS_LOOKAHEAD_LAYOUTCOMMIT 0x0040
#define NFS_LOOKAHEAD_SETATTR 0x0080
#define NFS_LOOKAHEAD_SETCLIENTID 0x0100
#define NFS_LOOKAHEAD_SETCLIENTID_CONFIRM 0x0200
#define NFS_LOOKAHEAD_LOOKUP 0x0400
#define NFS_LOOKAHEAD_READLINK 0x0800
/* ... */
struct nfs_request_lookahead {
uint32_t flags;
uint16_t read;
uint16_t write;
};
#define NFS_LOOKAHEAD_HIGH_LATENCY(lkhd) \
(((lkhd).flags & (NFS_LOOKAHEAD_READ | \
NFS_LOOKAHEAD_WRITE | \
NFS_LOOKAHEAD_COMMIT | \
NFS_LOOKAHEAD_LAYOUTCOMMIT | \
NFS_LOOKAHEAD_READDIR)))
#define XDR_ARRAY_MAXLEN 1024
#define XDR_BYTES_MAXLEN (1024*1024)
#define XDR_BYTES_MAXLEN_IO (64*1024*1024)
#define XDR_STRING_MAXLEN (8*1024)
typedef struct sockaddr_storage sockaddr_t;
#define SOCK_NAME_MAX 128
struct netconfig *getnetconfigent(const char *);
void freenetconfigent(struct netconfig *);
/**
* @addtogroup config
*
* @{
*/
/**
* @defgroup config_krb5 Structure and defaults for NFS_KRB5
* @brief Constants and csturctures for KRB5 configuration
*
* @{
*/
/**
* @brief Default value for krb5_param.gss.principal
*/
#define DEFAULT_NFS_PRINCIPAL "nfs"
/**
* @brief default value for krb5_param.keytab
*
* The empty string lets GSSAPI use keytab specified in /etc/krb5.conf
*/
#define DEFAULT_NFS_KEYTAB ""
/**
* @brief Kerberos 5 parameters
*/
typedef struct nfs_krb5_param {
/** Kerberos keytab. Defaults to DEFAULT_NFS_KEYTAB, settable
with KeytabPath. */
char *keytab;
/** The ganesha credential cache. Defautls to
DEFAULT_NFS_CCACHE_DIR, unsettable by user. */
char *ccache_dir;
/**
* @note representation of GSSAPI service, independent of GSSRPC or
* TI-RPC global variables. Initially, use it just for
* callbacks.
*/
struct {
/** Principal used in callbacks, set to
DEFAULT_NFS_PRINCIPAL and unsettable by user. */
char *principal;
/** Expanded gss name from principal, equal to
principal/host\@domain. Unsettable by user. */
gss_name_t gss_name;
} svc;
/** Whether to activate Kerberos 5. Defaults to true (if
Kerberos support is compiled in) and settable with
Active_krb5 */
bool active_krb5;
} nfs_krb5_parameter_t;
/** @} */
/** @} */
void log_sperror_gss(char *, OM_uint32, OM_uint32);
const char *str_gc_proc(rpc_gss_proc_t);
/* Private data associated with a new TI-RPC (TCP) SVCXPRT (transport
* connection), ie, xprt->xp_u1.
*/
#define XPRT_PRIVATE_FLAG_NONE SVC_XPRT_FLAG_NONE
/* uint16_t actually used */
#define XPRT_PRIVATE_FLAG_DECODING 0x0008
#define XPRT_PRIVATE_FLAG_STALLED 0x0010 /* ie, -on stallq- */
/* uint32_t instructions */
#define XPRT_PRIVATE_FLAG_LOCKED SVC_XPRT_FLAG_LOCKED
#define XPRT_PRIVATE_FLAG_UNLOCK SVC_XPRT_FLAG_UNLOCK
#define XPRT_PRIVATE_FLAG_INCREQ 0x00040000
#define XPRT_PRIVATE_FLAG_DECREQ 0x00080000
typedef struct gsh_xprt_private {
SVCXPRT *xprt;
struct glist_head stallq;
uint16_t flags;
} gsh_xprt_private_t;
static inline gsh_xprt_private_t *alloc_gsh_xprt_private(SVCXPRT *xprt,
uint32_t flags)
{
gsh_xprt_private_t *xu = (gsh_xprt_private_t *)
gsh_malloc(sizeof(gsh_xprt_private_t));
xu->xprt = xprt;
xu->flags = flags;
return xu;
}
#ifndef DRC_FLAG_RELEASE
#define DRC_FLAG_RELEASE 0x0040
#endif
static inline void free_gsh_xprt_private(SVCXPRT *xprt)
{
gsh_xprt_private_t *xu = (gsh_xprt_private_t *)xprt->xp_u1;
if (xu) {
gsh_free(xu);
xprt->xp_u1 = NULL;
}
}
static inline void gsh_xprt_ref(SVCXPRT *xprt, uint32_t flags,
const char *tag,
const int line)
{
if (flags & XPRT_PRIVATE_FLAG_INCREQ)
(void) atomic_inc_uint32_t(&xprt->xp_requests);
SVC_REF2(xprt, flags, tag, line);
/* !LOCKED */
LogFullDebugAlt(COMPONENT_DISPATCH, COMPONENT_RPC,
"xprt %p xp_requests=%" PRIu32 " xp_refs=%" PRIu32
" tag=%s line=%d",
xprt, xprt->xp_requests, xprt->xp_refs, tag, line);
}
static inline void gsh_xprt_unref(SVCXPRT *xprt, uint32_t flags,
const char *tag, const int line)
{
LogFullDebugAlt(COMPONENT_DISPATCH, COMPONENT_RPC,
"xprt %p prerelease xp_requests=%" PRIu32 " xp_refs=%" PRIu32
" tag=%s line=%d",
xprt, xprt->xp_requests, xprt->xp_refs, tag, line);
if (flags & XPRT_PRIVATE_FLAG_DECREQ)
(void) atomic_dec_uint32_t(&xprt->xp_requests);
if (flags & XPRT_PRIVATE_FLAG_DECODING) {
gsh_xprt_private_t *xu = (gsh_xprt_private_t *) xprt->xp_u1;
if (xu)
atomic_clear_uint16_t_bits(&xu->flags,
XPRT_PRIVATE_FLAG_DECODING);
}
LogFullDebugAlt(COMPONENT_DISPATCH, COMPONENT_RPC,
"xprt %p prerelease xp_requests=%" PRIu32 " xp_refs=%" PRIu32
" tag=%s line=%d",
xprt, xprt->xp_requests, xprt->xp_refs, tag, line);
SVC_RELEASE2(xprt, flags, tag, line);
/* !LOCKED */
}
static inline bool gsh_xprt_decoder_guard(SVCXPRT *xprt, uint32_t flags)
{
gsh_xprt_private_t *xu = (gsh_xprt_private_t *)xprt->xp_u1;
bool rslt = false;
if (xu->flags & XPRT_PRIVATE_FLAG_DECODING) {
LogDebug(COMPONENT_DISPATCH, "guard failed: flag %s",
"XPRT_PRIVATE_FLAG_DECODING");
goto unlock;
}
if (xu->flags & XPRT_PRIVATE_FLAG_STALLED) {
LogDebug(COMPONENT_DISPATCH, "guard failed: flag %s",
"XPRT_PRIVATE_FLAG_STALLED");
goto unlock;
}
atomic_set_uint16_t_bits(&xu->flags, XPRT_PRIVATE_FLAG_DECODING);
rslt = true;
unlock:
if (flags & XPRT_PRIVATE_FLAG_LOCKED)
PTHREAD_MUTEX_unlock(&xprt->xp_lock);
return rslt;
}
static inline void gsh_xprt_clear_flag(SVCXPRT *xprt, uint32_t flags)
{
if (flags & XPRT_PRIVATE_FLAG_DECODING) {
gsh_xprt_private_t *xu = (gsh_xprt_private_t *)xprt->xp_u1;
if (xu)
atomic_clear_uint16_t_bits(&xu->flags,
XPRT_PRIVATE_FLAG_DECODING);
}
if (flags & XPRT_PRIVATE_FLAG_LOCKED)
PTHREAD_MUTEX_unlock(&xprt->xp_lock);
}
#define DISP_SLOCK(x) \
do { \
if (!slocked) { \
if ((x)->xp_type == XPRT_UDP) { \
SVC_LOCK((x), XP_LOCK_SEND, __func__, \
__LINE__); \
slocked = true; \
} \
} \
} while (0)
#define DISP_SUNLOCK(x) \
do { \
if (slocked) { \
SVC_UNLOCK((x), XP_LOCK_SEND, __func__, __LINE__); \
slocked = false; \
} \
} while (0)
#define DISP_RLOCK(x) \
do { \
if (!rlocked) { \
SVC_LOCK((x), XP_LOCK_RECV, __func__, __LINE__); \
rlocked = true; \
} \
} while (0)
#define DISP_RUNLOCK(x) \
do { \
if (rlocked) { \
SVC_UNLOCK((x), XP_LOCK_RECV, __func__, __LINE__); \
rlocked = false; \
} \
} while (0)
bool copy_xprt_addr(sockaddr_t *, SVCXPRT *);
int display_sockaddr(struct display_buffer *dspbuf, sockaddr_t *addr);
static inline void sprint_sockaddr(sockaddr_t *addr, char *buf, size_t len)
{
struct display_buffer dspbuf = {len, buf, buf};
buf[0] = '\0';
display_sockaddr(&dspbuf, addr);
}
int sprint_sockip(sockaddr_t *, char *, int);
const char *xprt_type_to_str(xprt_type_t);
int cmp_sockaddr(sockaddr_t *, sockaddr_t *, bool);
int sockaddr_cmpf(sockaddr_t *, sockaddr_t *, bool);
uint64_t hash_sockaddr(sockaddr_t *, bool);
in_addr_t get_in_addr(sockaddr_t *);
int get_port(sockaddr_t *);
/* Returns an EAI value, accepts only numeric strings */
extern int ipstring_to_sockaddr(const char *, sockaddr_t *);
/* Serialized clnt_create and clnt_destroy */
CLIENT *gsh_clnt_create(char *, unsigned long, unsigned long, char *);
void gsh_clnt_destroy(CLIENT *);
extern tirpc_pkg_params ntirpc_pp;
#endif /* GSH_RPC_H */