1 #include "fwp_endpoint.h"
10 FWP_EPOINT_INACTIVE = 1,
11 FWP_EPOINT_UNBOUND = 2,
13 } fwp_endpoint_status_t;
16 * Structure of FWP endpoint.
21 fwp_endpoint_type_t type;
22 /**< the vres descriptor the send endpoint is bound to */
24 /**< for send enpoint it contains destination address
25 * for receive endpoint it is filled with the msg source address
27 struct fwp_sockaddr peer;
34 /**< socket descriptor*/
36 /**< specific operation options*/
38 fwp_endpoint_status_t status;
42 struct fwp_endpoint_table {
43 unsigned int nr_endpoints;
44 fwp_endpoint_t *entry;
46 } fwp_endpoint_table_t;
48 /* Global variable - endpoint table */
49 static fwp_endpoint_table_t fwp_endpoint_table = {
52 .lock = PTHREAD_MUTEX_INITIALIZER,
55 int fwp_endpoint_table_init(unsigned int nr_endpoints)
57 int table_size = nr_endpoints * sizeof(fwp_endpoint_t);
59 fwp_endpoint_table.entry = (fwp_endpoint_t*) malloc(table_size);
60 if (!fwp_endpoint_table.entry)
62 memset(fwp_endpoint_table.entry, 0, table_size);
63 fwp_endpoint_table.nr_endpoints = nr_endpoints;
67 static fwp_endpoint_t* fwp_endpoint_alloc()
71 /* find free vres id */
72 pthread_mutex_lock(&fwp_endpoint_table.lock);
74 nr_endpoints = fwp_endpoint_table.nr_endpoints;
75 while ((i < nr_endpoints) &&
76 (fwp_endpoint_table.entry[i].status != FWP_EPOINT_FREE))
79 if (i == nr_endpoints) {
80 pthread_mutex_unlock(&fwp_endpoint_table.lock);
84 fwp_endpoint_table.entry[i].status = FWP_EPOINT_INACTIVE;
85 pthread_mutex_unlock(&fwp_endpoint_table.lock);
86 return (&fwp_endpoint_table.entry[i]);
89 static inline void fwp_endpoint_free(fwp_endpoint_t *epoint)
91 epoint->status = FWP_EPOINT_FREE;
99 int fwp_endpoint_get_params(unsigned int *node, unsigned int *port, int *flags,
100 fwp_endpoint_d_t epointd)
102 fwp_endpoint_t *epoint = epointd;
104 *node = epoint->node;
105 *port = epoint->sport;
106 *flags = epoint->flags;
112 * Creates send endpoint
114 * \param[in] node IP address of destination node
115 * \param[in] port UDP port
117 * \return On success returns identifier of endpoint.
118 * On error, negative error code is returned.
122 int fwp_send_endpoint_create(unsigned int node, unsigned int port, int flags,
123 fwp_endpoint_d_t *epointdp)
125 struct sockaddr_in *addr;
126 fwp_endpoint_t *epoint;
130 epoint = fwp_endpoint_alloc();
135 epoint->type = FWP_SEND_EPOINT;
136 epoint->status = FWP_EPOINT_UNBOUND;
138 epoint->dport = port;
139 epoint->flags = flags;
141 addr = (struct sockaddr_in *)&(epoint->peer.addr);
142 bzero((char*) addr, sizeof(*addr));
143 addr->sin_family = AF_INET;
144 addr->sin_addr.s_addr = node;
145 addr->sin_port = htons(port);
146 epoint->peer.addrlen = sizeof(struct sockaddr_in);
148 if (flags && FWP_EPOINT_MNGT) {
149 if ((sockd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
150 perror("Unable to open socket");
154 if (connect(sockd,(struct sockaddr*) &epoint->peer.addr,
155 epoint->peer.addrlen)) {
157 perror("Connect error");
162 struct sockaddr_in myaddr;
164 bzero((char*) &myaddr, sizeof(myaddr));
165 myaddr.sin_family = AF_INET;
166 myaddr.sin_addr.s_addr = INADDR_ANY;
169 addrlen = sizeof(myaddr);
171 if ((sockd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
172 perror("Unable to open socket");
176 if (bind(sockd, (struct sockaddr*) &myaddr,
177 sizeof(myaddr)) == -1) {
179 perror("Bind error");
183 getsockname(sockd, (struct sockaddr*) &myaddr,
185 epoint->sport = myaddr.sin_port;
189 epoint->sockd = sockd;
190 FWP_DEBUG("Send endpoint created.\n");
195 fwp_endpoint_free(epoint);
200 * Creates receive endpoint
202 * \param[in] port UDP port
204 * \return On success returns identifier of endpoint.
205 * On error, negative error code is returned.
208 int fwp_receive_endpoint_create(unsigned int port, int flags,
209 fwp_endpoint_d_t *epointdp)
211 fwp_endpoint_t *epoint;
213 struct sockaddr_in *addr;
214 //int rcvbuf_size = 3000;
216 epoint = fwp_endpoint_alloc();
221 epoint->type = FWP_RECV_EPOINT;
222 epoint->status = FWP_EPOINT_UNBOUND;
223 epoint->flags = flags;
225 addr = (struct sockaddr_in *)&(epoint->peer.addr);
226 addr->sin_family = AF_INET;
227 addr->sin_addr.s_addr = INADDR_ANY;
228 addr->sin_port = htons(port);
229 epoint->peer.addrlen = sizeof(struct sockaddr_in);
231 if (flags && FWP_EPOINT_MNGT) {
232 if ((sockd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
233 perror("Unable to open socket");
237 if (bind(sockd, (struct sockaddr*) &epoint->peer.addr,
238 epoint->peer.addrlen) == -1) {
240 perror("Bind error");
244 if (listen(sockd,0)) {
245 perror("Connect error");
250 if ((sockd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
251 perror("Unable to open socket");
255 if (bind(sockd, (struct sockaddr*) &epoint->peer.addr,
256 epoint->peer.addrlen) == -1) {
258 perror("Bind error");
264 epoint->sockd = sockd;
265 /*if (setsockopt(epoint->sockd, SOL_SOCKET, SO_RCVBUF,
266 &rcvbuf_size, sizeof(rcvbuf_size)) == -1) {
268 perror("Unable to set socket buffer size");
271 FWP_DEBUG("Receive endpoint buffer size is set.\n");
275 getsockname(epoint->sockd, (struct sockaddr*)&epoint->peer.addr,
276 &epoint->peer.addrlen);
278 epoint->sport = addr->sin_port;
279 epoint->node = addr->sin_addr.s_addr;
280 FWP_DEBUG("Receive endpoint port=%d created.\n", ntohs(epoint->sport));
287 fwp_endpoint_free(epoint);
292 * Binds send endpoint to vres
294 * \param[in] vres_id identifier of vres
295 * \param[in] epoint_id send endpoint identifier
297 * \return On success returns 0. On error, negative error code is returned
299 int fwp_send_endpoint_bind(fwp_endpoint_d_t epointd, fwp_vres_d_t vresd)
301 fwp_endpoint_t *epoint = epointd;
303 if (epoint->type != FWP_SEND_EPOINT) {
307 /* link epoint-vres mutually */
308 pthread_mutex_lock(&fwp_endpoint_table.lock);
309 if (_fwp_vres_bind(vresd, epoint) < 0) {
310 pthread_mutex_unlock(&fwp_endpoint_table.lock);
314 if (epoint->type == FWP_EPOINT_BOUND) { /* if send endpoint is already bound */
315 fwp_send_endpoint_unbind(epoint);
318 epoint->vresd = vresd;
319 epoint->status = FWP_EPOINT_BOUND;
321 pthread_mutex_unlock(&fwp_endpoint_table.lock);
326 * Unbinds send endpoint from vres
328 * \param[in] id send endpoint identifier
329 * \return On success returns 0. On error, negative error code is returned
332 int fwp_send_endpoint_unbind(fwp_endpoint_d_t epointd)
334 fwp_endpoint_t *epoint = epointd;
336 /* unlink epoint-vres mutually */
337 _fwp_vres_unbind(epoint->vresd);
338 epoint->status = FWP_EPOINT_UNBOUND;
346 * \param[in] epoint_id identificator of endpoint
347 * \param[in] buffer buffer to store message
348 * \param[in] buffer_size size of buffer
351 * On success, it returns number of received bytes.
352 * On error, negative error code is returned,
355 ssize_t fwp_recv(fwp_endpoint_d_t epointd, void *buffer, size_t buffer_size)
357 fwp_endpoint_t *epoint = epointd;
358 fwp_sockaddr_t *peer = &epoint->peer;
361 _fwp_recvfrom(len, epoint->sockd, buffer, buffer_size, 0,
362 peer->addr, &peer->addrlen);
368 * Sends message through vres
370 * \param[in] epoint_id identificator of endpoint
371 * \param[in] msg message to sent
372 * \param[in] size message size
375 * On success, it returns zero.
376 * On error, negative error code is returned,
379 int fwp_send(fwp_endpoint_d_t epointd, void *msg, size_t size)
381 struct fwp_endpoint *epoint = epointd;
382 struct fwp_msgb *msgb;
384 /* TODO: Validity test of epointd */
385 if (epoint->status != FWP_EPOINT_BOUND) {
389 /*if (flags && MSG_DONTWAIT)
390 msgb = fwp_msgb_alloc(buffer_size);
392 if (!(msgb = fwp_msgb_alloc(size)))
395 msgb->peer = &epoint->peer;
396 /*msgb->data = msg;*/
397 /*msgb->flags = epoint->flags;*/
399 /* data must be copied since msg may change while
400 * message is waiting in transmission queue
402 memcpy(msgb->data, msg, size);
403 fwp_msgb_put(msgb, size);
404 /*msgb->tail = msgb->data + size;
409 return _fwp_vres_send(epoint->vresd, msgb);