2 #include <sys/types.h> /* socket defines */
3 #include <sys/socket.h> /* socket functions */
4 #include <stdlib.h> /* malloc() */
5 #include <linux/tipc.h> /* tipc stuff */
6 #include <stdint.h> /* uint32_t and friends */
7 #include <arpa/inet.h> /* htonls() and friends */
8 #include <string.h> /* memcpy() */
9 #include <unistd.h> /* close() */
13 #include "net-const.h"
20 * Miscelaneous helper functions
23 static void rep_send_error(const struct req_info
*req
, const unsigned int code
)
26 unsigned char minibuf
[3 * 4];
31 /* Network format: ID (4), REP_ERR (4), error code (4) */
34 memcpy(minibuf
, &(req
->id
), 4);
35 memcpy(minibuf
+ 4, &r
, 4);
36 memcpy(minibuf
+ 8, &c
, 4);
38 /* If this send fails, there's nothing to be done */
39 r
= sendto(req
->fd
, minibuf
, 3 * 4, 0, req
->clisa
, req
->clilen
);
42 errlog("rep_send_error() failed");
47 static int rep_send(const struct req_info
*req
, const unsigned char *buf
,
55 rv
= sendto(req
->fd
, buf
, size
, 0, req
->clisa
, req
->clilen
);
57 rep_send_error(req
, ERR_SEND
);
64 /* Send small replies, consisting in only a value. */
65 static void tipc_reply_mini(const struct req_info
*req
, uint32_t reply
)
67 /* We use a mini buffer to speedup the small replies, to avoid the
68 * malloc() overhead. */
69 unsigned char minibuf
[8];
75 memcpy(minibuf
, &(req
->id
), 4);
76 memcpy(minibuf
+ 4, &reply
, 4);
77 rep_send(req
, minibuf
, 8);
82 /* The tipc_reply_* functions are used by the db code to send the network
85 static void tipc_reply_err(const struct req_info
*req
, uint32_t reply
)
87 rep_send_error(req
, reply
);
90 static void tipc_reply_long(const struct req_info
*req
, uint32_t reply
,
91 unsigned char *val
, size_t vsize
)
95 tipc_reply_mini(req
, reply
);
101 reply
= htonl(reply
);
103 /* The reply length is:
109 bsize
= 4 + 4 + 4 + vsize
;
114 memcpy(buf
, &(req
->id
), 4);
115 memcpy(buf
+ 4, &reply
, 4);
116 memcpy(buf
+ 8, &t
, 4);
117 memcpy(buf
+ 12, val
, vsize
);
119 rep_send(req
, buf
, bsize
);
128 * Main functions for receiving and parsing
134 struct sockaddr_tipc srvsa
;
136 srvsa
.family
= AF_TIPC
;
137 if (settings
.tipc_lower
== settings
.tipc_upper
)
138 srvsa
.addrtype
= TIPC_ADDR_NAME
;
140 srvsa
.addrtype
= TIPC_ADDR_NAMESEQ
;
142 srvsa
.addr
.nameseq
.type
= TIPC_SERVER_TYPE
;
143 srvsa
.addr
.nameseq
.lower
= settings
.tipc_lower
;
144 srvsa
.addr
.nameseq
.upper
= settings
.tipc_upper
;
145 srvsa
.scope
= TIPC_CLUSTER_SCOPE
;
147 fd
= socket(AF_TIPC
, SOCK_RDM
, 0);
151 rv
= bind(fd
, (struct sockaddr
*) &srvsa
, sizeof(srvsa
));
161 void tipc_close(int fd
)
167 /* Static common buffer to avoid unnecessary allocations.
168 * Originally, this was malloc()ed, but making it static made it go from 27
169 * usec for each set operation, to 23 usec: it made test1 go from 3.213s to
170 * 2.345s for 37618 operations.
171 * Allocate enough to hold the max msg length of 64kbytes. */
172 #define SBSIZE (68 * 1024)
173 static unsigned char static_buf
[SBSIZE
];
175 /* Called by libevent for each receive event */
176 void tipc_recv(int fd
, short event
, void *arg
)
180 struct sockaddr_tipc clisa
;
183 clilen
= sizeof(clisa
);
185 rv
= recvfrom(fd
, static_buf
, SBSIZE
, 0, (struct sockaddr
*) &clisa
,
188 /* rv == 0 means "return of an undeliverable message", which
189 * we ignore; -1 means other error. */
194 stats
.net_broken_req
++;
201 req
.type
= REQTYPE_TIPC
;
202 req
.clisa
= (struct sockaddr
*) &clisa
;
204 req
.reply_mini
= tipc_reply_mini
;
205 req
.reply_err
= tipc_reply_err
;
206 req
.reply_long
= tipc_reply_long
;
208 /* parse the message */
209 parse_message(&req
, static_buf
, rv
);