/* * 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 #include #include #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