rx: For AFS_RXERRQ_ENV, retry sendmsg on error
[openafs.git] / src / rx / rx_internal.h
index 960f99a..b420a23 100644 (file)
-/*
- * Copyright (c) 2008, Your File System, Inc.
- * All rights reserved.
+/* Internal structures that are private to RX itself. These shouldn't be
+ * modified by library callers.
  *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, 
- *    this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the company nor the names of its contributors may 
- *    be used to endorse or promote products derived from this software 
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Data structures that are visible to security layers, but not to
+ * customers of RX belong in rx_private.h, which is installed.
  */
 
-#ifndef        _RX_INTERNAL_H_
-#define _RX_INTERNAL_H_
-
-#ifdef AFS_DARWIN80_ENV
-#include <libkern/OSAtomic.h>
-#endif
-#ifdef AFS_SUN58_ENV
-#include <sys/atomic.h>
+#ifdef AFS_RXERRQ_ENV
+# if defined(AFS_LINUX26_ENV) || defined(AFS_USR_LINUX26_ENV)
+#  include <linux/types.h>
+#  include <linux/errqueue.h>
+#  include <linux/icmp.h>
+# endif
 #endif
 
-#ifdef AFS_NT40_ENV
-#ifndef _WIN64
-#ifndef __cplusplus
-#include <intrin.h>
-#pragma intrinsic(_InterlockedOr)
-#pragma intrinsic(_InterlockedAnd)
-#define rx_AtomicOr(object, operand, mutex) _InterlockedOr(&object, operand)
-#define rx_AtomicAnd(object, operand, mutex) _InterlockedAnd(&object, operand)
-#endif /* __cplusplus */
-#else /* !WIN64 */
-#define rx_AtomicOr(object, operand, mutex) InterlockedOr(&object, operand)
-#define rx_AtomicAnd(object, operand, mutex) InterlockedAnd(&object, operand)
-#endif /* WIN64 */
-#define rx_AtomicIncrement_NL(object) InterlockedIncrement(&object)
-#define rx_AtomicIncrement(object, mutex) InterlockedIncrement(&object)
-#define rx_AtomicXor(object, operand, mutex) InterlockedXor(&object, operand)
-#define rx_AtomicAdd_NL(object, addend) InterlockedExchangeAdd(&object, addend)
-#define rx_AtomicAdd(object, addend, mutex) InterlockedExchangeAdd(&object, addend)
-#define rx_AtomicDecrement_NL(object) InterlockedDecrement(&object)
-#define rx_AtomicDecrement(object, mutex) InterlockedDecrement(&object)
-#define rx_AtomicSwap_NL(object1, object2) InterlockedExchange ((volatile LONG *) object1, object2);
-#define rx_AtomicSwap(object1, object2, mutex) InterlockedExchange ((volatile LONG *) object1, object2);
-#elif defined(AFS_DARWIN80_ENV)
-#define rx_AtomicIncrement_NL(object) OSAtomicIncrement32(&object)
-#define rx_AtomicIncrement(object, mutex) OSAtomicIncrement32(&object)
-#define rx_AtomicOr(object, operand, mutex) OSAtomicOr32(operand, &object)
-#define rx_AtomicAnd(object, operand, mutex) OSAtomicAnd32(operand, &object)
-#define rx_AtomicXor(object, operand, mutex) OSAtomicXor32(operand, &object)
-#define rx_AtomicAdd_NL(object, addend) OSAtomicAdd32(addend, &object)
-#define rx_AtomicAdd(object, addend, mutex) OSAtomicAdd32(addend, &object)
-#define rx_AtomicDecrement_NL(object) OSAtomicDecrement32(&object)
-#define rx_AtomicDecrement(object, mutex) OSAtomicDecrement32(&object)
-#define rx_AtomicSwap_NL(oldval, newval) rx_AtomicSwap_int(oldval, newval)
-#define rx_AtomicSwap(oldval, newval, mutex) rx_AtomicSwap_int(oldval, newval)
-static inline afs_int32 rx_AtomicSwap_int(afs_int32 *oldval, afs_int32 newval) {
-    afs_int32 ret = *oldval;
-    OSAtomicCompareAndSwap32 ((afs_int32) *oldval,(afs_int32) newval,
-                             (afs_int32*) oldval);
-    return ret;
-}
-#elif defined(AFS_SUN58_ENV)
-#define rx_AtomicIncrement_NL(object) atomic_inc_32(&object)
-#define rx_AtomicIncrement(object, mutex) atomic_inc_32(&object)
-#define rx_AtomicOr(object, operand, mutex) atomic_or_32(&object, operand)
-#define rx_AtomicAnd(object, operand, mutex) atomic_and_32(&object, operand)
-#define rx_AtomicAdd_NL(object, addend) atomic_add_32(&object, addend)
-#define rx_AtomicAdd(object, addend, mutex) atomic_add_32(&object, addend)
-#define rx_AtomicDecrement_NL(object) atomic_dec_32(&object)
-#define rx_AtomicDecrement(object, mutex) atomic_dec_32(&object)
-#define rx_AtomicSwap_NL(oldval, newval) rx_AtomicSwap_int(oldval, newval)
-#define rx_AtomicSwap(oldval, newval, mutex) rx_AtomicSwap_int(oldval, newval)
-static inline afs_int32 rx_AtomicSwap_int(afs_int32 *oldval, afs_int32 newval) {
-    afs_int32 ret = *oldval;
-    atomic_cas_32((afs_int32) *oldval,(afs_int32) newval,
-                 (afs_int32*) oldval);
-    return ret;
-}
+/* Globals that we don't want the world to know about */
+extern rx_atomic_t rx_nWaiting;
+extern rx_atomic_t rx_nWaited;
+
+/* How many times to retry sendmsg()-equivalent calls for AFS_RXERRQ_ENV. */
+#define RXI_SENDMSG_RETRY 8
+
+/* Prototypes for internal functions */
+
+/* rx.c */
+extern int rxi_IsRunning(void);
+extern void rxi_CancelDelayedAckEvent(struct rx_call *);
+extern void rxi_PacketsUnWait(void);
+extern void rxi_SetPeerMtu(struct rx_peer *peer, afs_uint32 host,
+                          afs_uint32 port, int mtu);
+#ifdef AFS_RXERRQ_ENV
+extern void rxi_ProcessNetError(struct sock_extended_err *err,
+                                afs_uint32 addr, afs_uint16 port);
+extern int osi_HandleSocketError(osi_socket sock, void *cmsgbuf,
+                                size_t cmsgbuf_len);
+extern void rxi_HandleSocketErrors(osi_socket sock);
 #else
-#define rx_AtomicIncrement_NL(object) (object)++
-#define rx_AtomicIncrement(object, mutex) rx_MutexIncrement(object, mutex)
-#define rx_AtomicOr(object, operand, mutex) rx_MutexOr(object, operand, mutex)
-#define rx_AtomicAnd(object, operand, mutex) rx_MutexAnd(object, operand, mutex)
-#define rx_AtomicAdd_NL(object, addend) (object += addend)
-#define rx_AtomicAdd(object, addend, mutex) rx_MutexAdd(object, addand, mutex)
-#define rx_AtomicDecrement_NL(object) (object)--
-#define rx_AtomicDecrement(object, mutex) rx_MutexDecrement(object, mutex)
-#define rx_AtomicSwap_NL(oldval, newval) rx_AtomicSwap_int(oldval, newval)
-#define rx_AtomicSwap(oldval, newval, mutex) rx_AtomicSwap_int(oldval, newval)
-static_inline afs_int32 rx_AtomicSwap_int(afs_int32 *oldval, afs_int32 newval) {
-    afs_int32 ret = *oldval;
-    *oldval = newval;
-    return ret;
-}
+# define rxi_HandleSocketErrors(sock) do { } while (0)
 #endif
-#define rx_AtomicPeek_NL(object) rx_AtomicAdd_NL(object, 0)
-#define rx_AtomicPeek(object, mutex) rx_AtomicAdd(object, 0, mutex)
-#define rx_MutexIncrement(object, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object++; \
-        MUTEX_EXIT(&mutex); \
-    } while(0)
-#define rx_MutexOr(object, operand, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object |= operand; \
-        MUTEX_EXIT(&mutex); \
-    } while(0)
-#define rx_MutexAnd(object, operand, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object &= operand; \
-        MUTEX_EXIT(&mutex); \
-    } while(0)
-#define rx_MutexXor(object, operand, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object ^= operand; \
-        MUTEX_EXIT(&mutex); \
-    } while(0)
-#define rx_MutexAdd(object, addend, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object += addend; \
-        MUTEX_EXIT(&mutex); \
-    } while(0)
-#define rx_MutexDecrement(object, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object--; \
-        MUTEX_EXIT(&mutex); \
-    } while(0)
-#define rx_MutexAdd1Increment2(object1, addend, object2, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object1 += addend; \
-        object2++; \
-        MUTEX_EXIT(&mutex); \
-    } while(0)
-#define rx_MutexAdd1Decrement2(object1, addend, object2, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object1 += addend; \
-        object2--; \
-        MUTEX_EXIT(&mutex); \
-    } while(0)
+extern struct rx_peer *rxi_FindPeer(afs_uint32 host, u_short port,
+                                   int create);
+extern struct rx_packet *rxi_ReceivePacket(struct rx_packet *np,
+                                          osi_socket socket, afs_uint32 host,
+                                          u_short port, int *tnop,
+                                          struct rx_call **newcallp);
+extern int rxi_IsConnInteresting(struct rx_connection *aconn);
+extern void rxi_PostDelayedAckEvent(struct rx_call *call, struct clock *now);
+extern void rxi_ConnectionError(struct rx_connection *conn, afs_int32 error);
+extern void rxi_Start(struct rx_call *call, int istack);
+extern void rxi_Send(struct rx_call *call, struct rx_packet *p, int istack);
+extern struct rx_packet *rxi_SendAck(struct rx_call *call,
+                                    struct rx_packet *optionalPacket,
+                                    int serial, int reason, int istack);
+extern struct rx_packet *rxi_SendConnectionAbort(struct rx_connection *conn,
+                                                struct rx_packet *packet,
+                                                int istack, int force);
+extern void rxi_IncrementTimeAndCount(struct rx_peer *peer,
+                                     afs_uint32 rxInterface,
+                                     afs_uint32 currentFunc,
+                                     afs_uint32 totalFunc,
+                                     struct clock *queueTime,
+                                     struct clock *execTime,
+                                     afs_uint64 bytesSent,
+                                     afs_uint64 bytesRcvd,
+                                     int isServer);
+#ifdef RX_ENABLE_LOCKS
+extern void rxi_WaitforTQBusy(struct rx_call *call);
+#else
+# define rxi_WaitforTQBusy(call)
+#endif
+
+/* rx_packet.h */
 
-#define rx_MutexAdd1AtomicIncrement2(object1, addend, object2, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object1 += addend; \
-        rx_AtomicIncrement(&object2); \
-        MUTEX_EXIT(&mutex); \
-    } while (0)
-#define rx_MutexAdd1AtomicDecrement2(object1, addend, object2, mutex) \
-    do { \
-        MUTEX_ENTER(&mutex); \
-        object1 += addend; \
-        rx_AtomicDecrement(&object2); \
-        MUTEX_EXIT(&mutex); \
-    } while (0)
-#endif /* _RX_INTERNAL_H */
+extern int rxi_SendIovecs(struct rx_connection *conn, struct iovec *iov,
+                         int iovcnt, size_t length, int istack);
+extern void rxi_SendRaw(struct rx_call *call, struct rx_connection *conn,
+                       int type, char *data, int bytes, int istack);