New upstream version 8.1.0
This commit is contained in:
194
client_module/source/common/net/sock/Socket.h
Normal file
194
client_module/source/common/net/sock/Socket.h
Normal file
@@ -0,0 +1,194 @@
|
||||
#ifndef SOCKET_H_
|
||||
#define SOCKET_H_
|
||||
|
||||
#include <common/toolkit/StringTk.h>
|
||||
#include <common/toolkit/Time.h>
|
||||
#include <common/Common.h>
|
||||
#include <common/net/sock/NicAddress.h>
|
||||
#include <linux/socket.h>
|
||||
#include <os/iov_iter.h>
|
||||
|
||||
|
||||
#define SOCKET_PEERNAME_LEN 24
|
||||
|
||||
/*
|
||||
* This is an abstract class.
|
||||
*/
|
||||
|
||||
|
||||
struct Socket;
|
||||
typedef struct Socket Socket;
|
||||
|
||||
|
||||
extern void _Socket_init(Socket* this);
|
||||
extern void _Socket_uninit(Socket* this);
|
||||
|
||||
extern bool Socket_bind(Socket* this, unsigned short port);
|
||||
extern bool Socket_bindToAddr(Socket* this, struct in_addr ipAddr, unsigned short port);
|
||||
|
||||
|
||||
|
||||
struct SocketOps
|
||||
{
|
||||
void (*uninit)(Socket* this);
|
||||
|
||||
bool (*connectByIP)(Socket* this, struct in_addr ipaddress, unsigned short port);
|
||||
bool (*bindToAddr)(Socket* this, struct in_addr ipaddress, unsigned short port);
|
||||
bool (*listen)(Socket* this);
|
||||
bool (*shutdown)(Socket* this);
|
||||
bool (*shutdownAndRecvDisconnect)(Socket* this, int timeoutMS);
|
||||
|
||||
ssize_t (*sendto)(Socket* this, struct iov_iter* iter, int flags, fhgfs_sockaddr_in *to);
|
||||
ssize_t (*recvT)(Socket* this, struct iov_iter* iter, int flags, int timeoutMS);
|
||||
};
|
||||
|
||||
struct Socket
|
||||
{
|
||||
NicAddrType_t sockType;
|
||||
char peername[SOCKET_PEERNAME_LEN];
|
||||
struct in_addr peerIP;
|
||||
int boundPort;
|
||||
|
||||
const struct SocketOps* ops;
|
||||
|
||||
struct {
|
||||
struct list_head _list;
|
||||
short _events;
|
||||
short revents;
|
||||
} poll;
|
||||
};
|
||||
|
||||
|
||||
static inline NicAddrType_t Socket_getSockType(Socket* this)
|
||||
{
|
||||
return this->sockType;
|
||||
}
|
||||
|
||||
static inline char* Socket_getPeername(Socket* this)
|
||||
{
|
||||
return this->peername;
|
||||
}
|
||||
|
||||
static inline struct in_addr Socket_getPeerIP(Socket* this)
|
||||
{
|
||||
return this->peerIP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the virtual uninit method and kfrees the object.
|
||||
*/
|
||||
static inline void Socket_virtualDestruct(Socket* this)
|
||||
{
|
||||
this->ops->uninit(this);
|
||||
kfree(this);
|
||||
}
|
||||
|
||||
static inline ssize_t Socket_recvT(Socket* this, struct iov_iter *iter,
|
||||
size_t length, int flags, int timeoutMS)
|
||||
{
|
||||
// TODO: implementation function should accept length as well.
|
||||
struct iov_iter copy = *iter;
|
||||
iov_iter_truncate(©, length);
|
||||
|
||||
{
|
||||
ssize_t nread = this->ops->recvT(this, ©, flags, timeoutMS);
|
||||
|
||||
if (nread >= 0)
|
||||
{
|
||||
// TODO: currently some parts of the project expect that we advance
|
||||
// the iov_iter. But as it turns out, advancing here does not mesh
|
||||
// well with how iov_iter is supposed to be used. A problem can be
|
||||
// observed when advancing an iov_iter of type ITER_PIPE. This will
|
||||
// result in mutation of external state (struct pipe_inode_info). IOW
|
||||
// we can't just make a copy of any iov_iter and advance that in
|
||||
// isolation.
|
||||
//
|
||||
// That means, the code should be changed such that we advance only in
|
||||
// the outermost layers of the beegfs client module.
|
||||
|
||||
iov_iter_advance(iter, nread);
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
}
|
||||
|
||||
static inline ssize_t Socket_recvT_kernel(Socket* this, void *buffer,
|
||||
size_t length, int flags, int timeoutMS)
|
||||
{
|
||||
struct iov_iter *iter = STACK_ALLOC_BEEGFS_ITER_KVEC(buffer, length, READ);
|
||||
return this->ops->recvT(this, iter, flags, timeoutMS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive with timeout, extended version with numReceivedBeforeError.
|
||||
*
|
||||
* note: this uses a soft timeout that is being reset after each received data packet.
|
||||
*
|
||||
* @param outNumReceivedBeforeError number of bytes received before returning (also set in case of
|
||||
* an error, e.g. timeout); given value will only be increased and is intentionally not set to 0
|
||||
* initially.
|
||||
* @return -ETIMEDOUT on timeout.
|
||||
*/
|
||||
static inline ssize_t Socket_recvExactTEx(Socket* this, struct iov_iter *iter, size_t len, int flags, int timeoutMS,
|
||||
size_t* outNumReceivedBeforeError)
|
||||
{
|
||||
ssize_t missingLen = len;
|
||||
|
||||
do
|
||||
{
|
||||
ssize_t recvRes = this->ops->recvT(this, iter, flags, timeoutMS);
|
||||
|
||||
if(unlikely(recvRes <= 0) )
|
||||
return recvRes;
|
||||
|
||||
missingLen -= recvRes;
|
||||
*outNumReceivedBeforeError += recvRes;
|
||||
|
||||
} while(missingLen);
|
||||
|
||||
// all received if we got here
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline ssize_t Socket_recvExactTEx_kernel(Socket* this, void *buf, size_t len, int flags, int timeoutMS,
|
||||
size_t* outNumReceivedBeforeError)
|
||||
{
|
||||
struct iov_iter *iter = STACK_ALLOC_BEEGFS_ITER_KVEC(buf, len, READ);
|
||||
return Socket_recvExactTEx(this, iter, len, flags, timeoutMS, outNumReceivedBeforeError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive with timeout.
|
||||
*
|
||||
* @return -ETIMEDOUT on timeout.
|
||||
*/
|
||||
static inline ssize_t Socket_recvExactT(Socket* this, struct iov_iter *iter, size_t len, int flags, int timeoutMS)
|
||||
{
|
||||
size_t numReceivedBeforeError;
|
||||
|
||||
return Socket_recvExactTEx(this, iter, len, flags, timeoutMS, &numReceivedBeforeError);
|
||||
}
|
||||
static inline ssize_t Socket_recvExactT_kernel(Socket* this, void *buf, size_t len, int flags, int timeoutMS)
|
||||
{
|
||||
size_t numReceivedBeforeError;
|
||||
|
||||
return Socket_recvExactTEx_kernel(this, buf, len, flags, timeoutMS, &numReceivedBeforeError);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline ssize_t Socket_sendto_kernel(Socket *this, const void *buf, size_t len, int flags,
|
||||
fhgfs_sockaddr_in *to)
|
||||
{
|
||||
struct iov_iter *iter = STACK_ALLOC_BEEGFS_ITER_KVEC(buf, len, WRITE);
|
||||
return this->ops->sendto(this, iter, flags, to);
|
||||
}
|
||||
|
||||
static inline ssize_t Socket_send_kernel(Socket *this, const void *buf, size_t len, int flags)
|
||||
{
|
||||
return Socket_sendto_kernel(this, buf, len, flags, NULL);
|
||||
}
|
||||
|
||||
|
||||
#endif /*SOCKET_H_*/
|
||||
Reference in New Issue
Block a user