1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 #ifndef _KRRP_CONNECTION_H
  17 #define _KRRP_CONNECTION_H
  18 
  19 #include <sys/sysmacros.h>
  20 #include <sys/kmem.h>
  21 #include <sys/stream.h>
  22 #include <sys/list.h>
  23 #include <sys/modctl.h>
  24 #include <sys/proc.h>
  25 #include <sys/class.h>
  26 #include <inet/ip.h>
  27 #include <sys/ksocket.h>
  28 #include <sys/cmn_err.h>
  29 
  30 #include <krrp_error.h>
  31 
  32 #include "krrp_pdu.h"
  33 #include "krrp_protocol.h"
  34 #include "krrp_queue.h"
  35 
  36 #ifdef __cplusplus
  37 extern "C" {
  38 #endif
  39 
  40 #define KRRP_RX_TIMEOUT 60 /* In seconds */
  41 
  42 typedef struct krrp_conn_s krrp_conn_t;
  43 
  44 typedef enum {
  45         KRRP_CONN_DATA_PDU,
  46         KRRP_CONN_CTRL_PDU,
  47         KRRP_CONN_ERROR,
  48 } krrp_conn_cb_ev_t;
  49 
  50 typedef void (krrp_conn_cb_t)(void *void_conn,
  51     krrp_conn_cb_ev_t ev, uintptr_t ev_arg, void *cb_arg);
  52 
  53 typedef void (krrp_get_data_pdu_cb_t)(void *cb_arg, krrp_pdu_t **result_pdu);
  54 
  55 typedef enum {
  56         KRRP_CS_CONNECTED,
  57         KRRP_CS_READY_TO_RUN,
  58         KRRP_CS_ACTIVE,
  59         KRRP_CS_STOPPED,
  60         KRRP_CS_DISCONNECTING,
  61         KRRP_CS_DISCONNECTED
  62 } krrp_conn_state_t;
  63 
  64 typedef struct krrp_throttle_s {
  65         kmutex_t                mtx;
  66         kcondvar_t              cv;
  67         timeout_id_t    timer;
  68         size_t                  remains;
  69         size_t                  limit;
  70 } krrp_throttle_t;
  71 
  72 struct krrp_conn_s {
  73         krrp_conn_state_t               state;
  74 
  75         boolean_t                               tx_running;
  76         boolean_t                               rx_running;
  77 
  78         krrp_queue_t                    *ctrl_tx_queue;
  79 
  80         krrp_get_data_pdu_cb_t  *get_data_pdu_cb;
  81         void                                    *get_data_pdu_cb_arg;
  82 
  83         krrp_conn_cb_t                  *callback;
  84         void                                    *callback_arg;
  85 
  86         kmutex_t                                mtx;
  87         kcondvar_t                              cv;
  88         ksocket_t                               ks;
  89 
  90         krrp_throttle_t                 throttle;
  91 
  92         size_t                                  mblk_wroff;
  93         size_t                                  mblk_tail_len;
  94         size_t                                  blk_sz;
  95 
  96         uint64_t                                bytes_tx;
  97         uint64_t                                bytes_rx;
  98 
  99         uint64_t                                cur_txg;
 100 
 101         krrp_pdu_engine_t               *data_pdu_engine;
 102 
 103         timeout_id_t                    action_timeout;
 104 };
 105 
 106 int krrp_conn_create_from_scratch(krrp_conn_t **result_conn,
 107     const char *address, int port, int timeout, krrp_error_t *error);
 108 int krrp_conn_create_from_ksocket(krrp_conn_t **result_conn,
 109     ksocket_t ks, krrp_error_t *error);
 110 void krrp_conn_destroy(krrp_conn_t *conn);
 111 
 112 void krrp_conn_register_callback(krrp_conn_t *conn,
 113     krrp_conn_cb_t *ev_cb, void *cb_arg);
 114 
 115 void krrp_conn_throttle_set(krrp_conn_t *conn, size_t new_limit,
 116     boolean_t only_set);
 117 
 118 void krrp_conn_run(krrp_conn_t *conn, krrp_queue_t *ctrl_tx_queue,
 119     krrp_pdu_engine_t *data_pdu_engine,
 120     krrp_get_data_pdu_cb_t *get_data_pdu_cb, void *cb_arg);
 121 void krrp_conn_stop(krrp_conn_t *conn);
 122 
 123 int krrp_conn_send_ctrl_data(krrp_conn_t *conn, krrp_opcode_t opcode,
 124     nvlist_t *nvl, krrp_error_t *error);
 125 int krrp_conn_tx_ctrl_pdu(krrp_conn_t *conn, krrp_pdu_ctrl_t *pdu,
 126     krrp_error_t *error);
 127 int krrp_conn_rx_ctrl_pdu(krrp_conn_t *conn, krrp_pdu_ctrl_t **result_pdu,
 128     krrp_error_t *error);
 129 
 130 #ifdef __cplusplus
 131 }
 132 #endif
 133 
 134 #endif /* _KRRP_CONNECTION_H */