mirror of
https://github.com/schoebel/mars
synced 2024-12-22 06:40:52 +00:00
223 lines
6.3 KiB
C
223 lines
6.3 KiB
C
/*
|
|
* MARS Long Distance Replication Software
|
|
*
|
|
* This file is part of MARS project: http://schoebel.github.io/mars/
|
|
*
|
|
* Copyright (C) 2010-2014 Thomas Schoebel-Theuer
|
|
* Copyright (C) 2011-2014 1&1 Internet AG
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#ifndef MARS_NET_H
|
|
#define MARS_NET_H
|
|
|
|
#include <net/sock.h>
|
|
#include <net/ipconfig.h>
|
|
#include <net/tcp.h>
|
|
|
|
#include "brick.h"
|
|
|
|
extern int mars_net_default_port;
|
|
extern bool mars_net_is_alive;
|
|
|
|
extern __u32 enabled_net_compressions;
|
|
extern __u32 used_net_compression;
|
|
|
|
/* This needs to be incremented when low-level network protocol
|
|
* details (as opposed to mid-level changes to struct meta)
|
|
* are changing.
|
|
* Another use case is high-level changes in the order of messages
|
|
* which cannot be neither encoded into usable_features_version
|
|
* nor into usable_strategy_version.
|
|
*/
|
|
#define MARS_PROTO_LEVEL 2
|
|
|
|
#define MAX_FIELD_LEN 32
|
|
#define MAX_DESC_CACHE 16
|
|
|
|
struct mars_desc_cache {
|
|
u64 cache_sender_cookie;
|
|
u64 cache_recver_cookie;
|
|
s32 cache_items;
|
|
};
|
|
|
|
struct mars_desc_item {
|
|
char field_name[MAX_FIELD_LEN];
|
|
s32 field_type;
|
|
s32 field_size;
|
|
s32 field_sender_offset;
|
|
s32 field_recver_offset;
|
|
};
|
|
|
|
/* The original struct socket has no refcount. This leads to problems
|
|
* during long-lasting system calls when racing with socket shutdown.
|
|
*
|
|
* The original idea of struct mars_socket was just a small wrapper
|
|
* adding a refcount and some debugging aid.
|
|
* Later, some buffering was added in order to take advantage of
|
|
* kernel_sendpage().
|
|
* Caching of meta description has also been added.
|
|
*/
|
|
struct mars_socket {
|
|
struct socket *s_socket;
|
|
void *s_buffer;
|
|
atomic_t s_count;
|
|
int s_remote_proto_level; /* corresponds to MARS_PROTO_LEVEL of remote site */
|
|
int s_common_proto_level; /* common denominator of protocol levels */
|
|
int s_pos;
|
|
int s_debug_nr;
|
|
int s_send_abort;
|
|
int s_recv_abort;
|
|
int s_send_cnt;
|
|
int s_recv_cnt;
|
|
bool s_shutdown_on_err;
|
|
bool s_alive;
|
|
bool s_connected;
|
|
struct mars_desc_cache *s_desc_send[MAX_DESC_CACHE];
|
|
struct mars_desc_cache *s_desc_recv[MAX_DESC_CACHE];
|
|
};
|
|
|
|
struct mars_tcp_params {
|
|
int ip_tos;
|
|
int tcp_window_size;
|
|
int tcp_nodelay;
|
|
int tcp_timeout;
|
|
int tcp_keepcnt;
|
|
int tcp_keepintvl;
|
|
int tcp_keepidle;
|
|
};
|
|
|
|
enum mars_traffic_types {
|
|
MARS_TRAFFIC_META,
|
|
MARS_TRAFFIC_REPLICATION,
|
|
MARS_TRAFFIC_SYNC,
|
|
MARS_TRAFFIC_MAX /* this must come last */
|
|
} __packed;
|
|
|
|
extern struct mars_tcp_params mars_tcp_params[MARS_TRAFFIC_MAX];
|
|
|
|
/* Do not change the order, only append new members */
|
|
enum {
|
|
CMD_NOP,
|
|
CMD_NOTIFY,
|
|
CMD_CONNECT,
|
|
CMD_GETINFO,
|
|
CMD_GETENTS,
|
|
CMD_MREF,
|
|
CMD_CB,
|
|
CMD_PUSH_LINK,
|
|
CMD_PUSH_CHECK,
|
|
/* keep last element */
|
|
CMD_LAST
|
|
} __packed;
|
|
|
|
#define CMD_FLAG_MASK 255
|
|
#define CMD_FLAG_HAS_DATA 256
|
|
|
|
struct mars_cmd {
|
|
struct lamport_time cmd_stamp; // for automatic lamport clock
|
|
int cmd_proto;
|
|
int cmd_code;
|
|
__u32 cmd_compr_flags;
|
|
int cmd_compr_len;
|
|
int cmd_int1;
|
|
//int cmd_int2;
|
|
//int cmd_int3;
|
|
const char *cmd_str1;
|
|
const char *cmd_str2;
|
|
//char *cmd_str3;
|
|
};
|
|
|
|
extern char *(*mars_translate_hostname)(const char *name);
|
|
|
|
/* Low-level network traffic
|
|
*/
|
|
extern int mars_create_sockaddr(struct sockaddr_storage *addr, const char *spec);
|
|
|
|
extern int mars_create_socket(struct mars_socket *msock,
|
|
struct sockaddr_storage *addr,
|
|
struct mars_tcp_params *params,
|
|
bool is_server);
|
|
extern int mars_accept_socket(struct mars_socket *new_msock,
|
|
struct mars_socket *old_msock,
|
|
struct mars_tcp_params *params);
|
|
extern bool mars_get_socket(struct mars_socket *msock);
|
|
extern void mars_put_socket(struct mars_socket *msock);
|
|
extern void mars_shutdown_socket(struct mars_socket *msock);
|
|
extern bool mars_socket_is_alive(struct mars_socket *msock);
|
|
extern long mars_socket_send_space_available(struct mars_socket *msock);
|
|
|
|
extern int mars_send_raw(struct mars_socket *msock, const void *buf, int len, bool cork);
|
|
extern int mars_recv_raw(struct mars_socket *msock, void *buf, int minlen, int maxlen);
|
|
|
|
extern inline bool _socket_is_connecting(struct socket *sock)
|
|
{
|
|
return (sock->state == SS_CONNECTING);
|
|
}
|
|
|
|
extern inline bool _socket_not_connected(struct socket *sock)
|
|
{
|
|
return (sock->state != SS_CONNECTED);
|
|
}
|
|
|
|
extern inline bool mars_socket_is_connecting(struct mars_socket *msock)
|
|
{
|
|
return msock->s_socket &&
|
|
_socket_is_connecting(msock->s_socket);
|
|
}
|
|
|
|
extern inline bool mars_socket_not_connected(struct mars_socket *msock)
|
|
{
|
|
return !msock->s_socket ||
|
|
_socket_not_connected(msock->s_socket);
|
|
}
|
|
|
|
/* Mid-level generic field data exchange
|
|
*/
|
|
extern int mars_send_struct(struct mars_socket *msock, const void *data, const struct meta *meta, bool cork);
|
|
#define mars_recv_struct(_sock_,_data_,_meta_) \
|
|
({ \
|
|
_mars_recv_struct(_sock_, _data_, _meta_, __LINE__); \
|
|
})
|
|
extern int _mars_recv_struct(struct mars_socket *msock, void *data, const struct meta *meta, int line);
|
|
|
|
/* High-level transport of mars structures
|
|
*/
|
|
|
|
extern int mars_send_cmd(struct mars_socket *msock, struct mars_cmd *cmd, bool cork);
|
|
extern int _mars_recv_cmd(struct mars_socket *msock, struct mars_cmd *cmd, int line);
|
|
#define mars_recv_cmd(_sock_,_cmd_) \
|
|
({ \
|
|
_mars_recv_cmd(_sock_, _cmd_, __LINE__); \
|
|
})
|
|
|
|
#define MARS_NET_MREF_DATA_MAX (PAGE_SIZE)
|
|
|
|
extern int mars_send_mref(struct mars_socket *msock, struct mref_object *mref, bool cork);
|
|
extern int mars_recv_mref(struct mars_socket *msock, struct mref_object *mref, struct mars_cmd *cmd);
|
|
extern int mars_send_cb(struct mars_socket *msock, struct mref_object *mref, bool cork);
|
|
extern int mars_recv_cb(struct mars_socket *msock, struct mref_object *mref, struct mars_cmd *cmd);
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
// init
|
|
|
|
extern int init_mars_net(void);
|
|
extern void exit_mars_net(void);
|
|
|
|
|
|
#endif
|