session: update due to clib_socket refactoring
[vpp.git] / src / vppinfra / socket.h
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16   Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17
18   Permission is hereby granted, free of charge, to any person obtaining
19   a copy of this software and associated documentation files (the
20   "Software"), to deal in the Software without restriction, including
21   without limitation the rights to use, copy, modify, merge, publish,
22   distribute, sublicense, and/or sell copies of the Software, and to
23   permit persons to whom the Software is furnished to do so, subject to
24   the following conditions:
25
26   The above copyright notice and this permission notice shall be
27   included in all copies or substantial portions of the Software.
28
29   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 */
37
38 #ifndef _clib_included_socket_h
39 #define _clib_included_socket_h
40
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44
45 #include <vppinfra/clib.h>
46 #include <vppinfra/error.h>
47 #include <vppinfra/format.h>
48
49 typedef enum
50 {
51   CLIB_SOCKET_TYPE_UNKNOWN = 0,
52   CLIB_SOCKET_TYPE_INET,
53   CLIB_SOCKET_TYPE_UNIX,
54 #if CLIB_LINUX
55   CLIB_SOCKET_TYPE_LINUX_ABSTRACT,
56 #endif
57 } clib_socket_type_t;
58
59 typedef struct _socket_t
60 {
61   /* File descriptor. */
62   i32 fd;
63
64   /* Config string for socket HOST:PORT or just HOST. */
65   char *config;
66
67   union
68   {
69     struct
70     {
71       u32 is_server : 1;
72       u32 rx_end_of_file : 1;
73       u32 non_blocking_connect : 1;
74       u32 allow_group_write : 1;
75       u32 is_seqpacket : 1;
76       u32 passcred : 1;
77       u32 is_blocking : 1;
78       u32 local_only : 1;
79     };
80     u32 flags;
81   };
82
83   /* Transmit buffer.  Holds data waiting to be written. */
84   u8 *tx_buffer;
85
86   /* Receive buffer.  Holds data read from socket. */
87   u8 *rx_buffer;
88
89   /* Peer socket we are connected to. */
90   struct sockaddr_in peer;
91
92   /* Credentials, populated if CLIB_SOCKET_F_PASSCRED is set */
93   pid_t pid;
94   uid_t uid;
95   gid_t gid;
96
97   clib_error_t *(*write_func) (struct _socket_t * sock);
98   clib_error_t *(*read_func) (struct _socket_t * sock, int min_bytes);
99   clib_error_t *(*close_func) (struct _socket_t * sock);
100   clib_error_t *(*recvmsg_func) (struct _socket_t * s, void *msg, int msglen,
101                                  int fds[], int num_fds);
102   clib_error_t *(*sendmsg_func) (struct _socket_t * s, void *msg, int msglen,
103                                  int fds[], int num_fds);
104   clib_socket_type_t type;
105   uword private_data;
106 } clib_socket_t;
107
108 #define CLIB_SOCKET_FLAG(f)             (((clib_socket_t){ .f = 1 }).flags)
109 #define CLIB_SOCKET_F_IS_CLIENT         0
110 #define CLIB_SOCKET_F_IS_SERVER         CLIB_SOCKET_FLAG (is_server)
111 #define CLIB_SOCKET_F_ALLOW_GROUP_WRITE CLIB_SOCKET_FLAG (allow_group_write)
112 #define CLIB_SOCKET_F_SEQPACKET         CLIB_SOCKET_FLAG (is_seqpacket)
113 #define CLIB_SOCKET_F_PASSCRED          CLIB_SOCKET_FLAG (passcred)
114 #define CLIB_SOCKET_F_BLOCKING          CLIB_SOCKET_FLAG (is_blocking)
115
116 /* socket config format is host:port.
117    Unspecified port causes a free one to be chosen starting
118    from IPPORT_USERRESERVED (5000). */
119 clib_error_t *clib_socket_init (clib_socket_t * socket);
120
121 clib_error_t *clib_socket_accept (clib_socket_t * server,
122                                   clib_socket_t * client);
123
124 int clib_socket_prefix_is_valid (char *s);
125 int clib_socket_prefix_get_type (char *s);
126
127 always_inline uword
128 clib_socket_is_server (clib_socket_t * sock)
129 {
130   return sock->is_server;
131 }
132
133 always_inline uword
134 clib_socket_is_client (clib_socket_t * s)
135 {
136   return !clib_socket_is_server (s);
137 }
138
139 always_inline uword
140 clib_socket_is_connected (clib_socket_t * sock)
141 {
142   return sock->fd > 0;
143 }
144
145
146 always_inline int
147 clib_socket_rx_end_of_file (clib_socket_t * s)
148 {
149   return s->rx_end_of_file;
150 }
151
152 always_inline void *
153 clib_socket_tx_add (clib_socket_t * s, int n_bytes)
154 {
155   u8 *result;
156   vec_add2 (s->tx_buffer, result, n_bytes);
157   return result;
158 }
159
160 always_inline void
161 clib_socket_tx_add_va_formatted (clib_socket_t * s, char *fmt, va_list * va)
162 {
163   s->tx_buffer = va_format (s->tx_buffer, fmt, va);
164 }
165
166 always_inline clib_error_t *
167 clib_socket_tx (clib_socket_t * s)
168 {
169   return s->write_func (s);
170 }
171
172 always_inline clib_error_t *
173 clib_socket_rx (clib_socket_t * s, int n_bytes)
174 {
175   return s->read_func (s, n_bytes);
176 }
177
178 always_inline clib_error_t *
179 clib_socket_sendmsg (clib_socket_t * s, void *msg, int msglen,
180                      int fds[], int num_fds)
181 {
182   return s->sendmsg_func (s, msg, msglen, fds, num_fds);
183 }
184
185 always_inline clib_error_t *
186 clib_socket_recvmsg (clib_socket_t * s, void *msg, int msglen,
187                      int fds[], int num_fds)
188 {
189   return s->recvmsg_func (s, msg, msglen, fds, num_fds);
190 }
191
192 always_inline void
193 clib_socket_free (clib_socket_t * s)
194 {
195   vec_free (s->tx_buffer);
196   vec_free (s->rx_buffer);
197   if (clib_mem_is_heap_object (s->config))
198     vec_free (s->config);
199   clib_memset (s, 0, sizeof (s[0]));
200 }
201
202 always_inline clib_error_t *
203 clib_socket_close (clib_socket_t * sock)
204 {
205   clib_error_t *err;
206   err = (*sock->close_func) (sock);
207   return err;
208 }
209
210 void clib_socket_tx_add_formatted (clib_socket_t * s, char *fmt, ...);
211
212 #endif /* _clib_included_socket_h */
213
214 /*
215  * fd.io coding-style-patch-verification: ON
216  *
217  * Local Variables:
218  * eval: (c-set-style "gnu")
219  * End:
220  */