Add counters for MPTP buffers and syscalls.
[swifty.git] / src / lib / lib_swift.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <unistd.h>
10
11 #define DEBUG
12 #include "lib_swift.h"
13
14 /*
15  * TODO: send ssa as pointer
16  */
17
18 void transformFromAddrToSwift(struct sockSwiftaddr *ssa, struct listsockaddr lsa)
19 {
20         int i;
21         
22         Dprintf("transform in %d address\n", lsa.N);    
23         ssa->sin_addr.N = lsa.N;
24         if (lsa.N > 0) {
25                 ssa->sin_family = lsa.sa[0].sin_family;
26                 ssa->sin_port = lsa.sa[0].sin_port;
27         }
28         
29         for (i = 0; i < lsa.N; i++)
30         {
31                 ssa->sin_addr.s_addr[i] = lsa.sa[i].sin_addr.s_addr;
32         }
33 }
34
35 /*
36  * TODO: send ssa as pointer
37  */
38
39 void transformFromSwiftToAddr(struct listsockaddr *lsa, struct sockSwiftaddr ssa)
40 {
41         int i;
42         
43         Dprintf("transform %d address\n", ssa.sin_addr.N);
44         lsa->N = ssa.sin_addr.N;
45         
46         for ( i = 0; i < lsa->N; i++) {
47                 lsa->sa[i].sin_family = ssa.sin_family;
48                 lsa->sa[i].sin_port = ssa.sin_port;
49                 lsa->sa[i].sin_addr.s_addr = ssa.sin_addr.s_addr[i];
50         }
51 }
52
53 // Function to receive a message
54 ssize_t recvfromSwift(Swift s, void *buf, size_t len, int flags,
55                                           struct sockSwiftaddr *from, socklen_t fromlen)
56 {
57         struct sockaddr s_other;
58         socklen_t slen=sizeof(s_other); 
59         ssize_t rec = -1, send;
60         char *command = "test";
61         struct listsockaddr lsa;
62         int i, channel;
63         
64         transformFromSwiftToAddr(&lsa, *from);
65         Dprintf("create recv channel\n");       
66         // TODO make pool
67         if (s->usedChannels < s->maxChannels) 
68         {
69                 channel = s->usedChannels++;
70                 CHECK(s->recvChannel[channel] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
71
72                 for ( i = 0 ; i < lsa.N ; i++) 
73                 {
74                         Dprintf("send information to %s:%d\n", inet_ntoa(lsa.sa[i].sin_addr), ntohs(lsa.sa[i].sin_port));                       
75                         send = sendto(s->recvChannel[channel], command, 4, 0, (const struct sockaddr *)&lsa.sa[i], sizeof(lsa.sa[i]));
76                 }
77                 
78                 Dprintf("receive data\n");
79                 // TODO make a non-blocant select
80                 // I'm waiting for response
81                 rec = recvfrom(s->recvChannel[channel], buf, len, flags,  (struct sockaddr * __restrict__)&s_other, &slen);             
82         
83                 close(s->recvChannel[channel]);
84                 s->usedChannels--;
85         }
86         return rec;
87 }
88
89 // Function to send a message
90 ssize_t sendToSwift(Swift s, const void *buf, size_t len, int flags, 
91                                         const struct sockSwiftaddr *to, socklen_t tolen) 
92 {
93         struct listsockaddr lsa;
94         int i;
95         ssize_t send = -1;
96         
97         transformFromSwiftToAddr(&lsa, *to);
98         
99         for ( i = 0 ; i < lsa.N ; i++) 
100         {
101                 Dprintf("send data to %s:%d\n", inet_ntoa(lsa.sa[i].sin_addr), ntohs(lsa.sa[i].sin_port));
102                 send = sendto(s->sendChannel, buf, len, flags, (const struct sockaddr *)&lsa.sa[i], sizeof(lsa.sa[i]));
103         }
104         
105         return send;
106 }
107 // Function to listen to a port
108 int listenfromSwift (Swift s, void *buf, size_t len, int flags,
109                                          struct sockSwiftaddr * from, socklen_t *fromlen) 
110 {
111         struct sockaddr s_other;
112         struct listsockaddr lsa;
113         socklen_t slen=sizeof(s_other); 
114         ssize_t rec;
115         
116         Dprintf("wait to receive messages\n");
117         
118         rec = recvfrom(s->socketListener, buf, len, flags,  (struct sockaddr * __restrict__)&s_other, &slen);
119         
120         // fill listsockaddr
121         memcpy(&lsa.sa[0], &s_other, sizeof(s_other));
122         lsa.N = 1;
123         
124         transformFromAddrToSwift(from, lsa);
125         
126         return rec;
127 }
128
129 // Function to bind a port for swift socket
130 int bindSwift(Swift s, const struct sockSwiftaddr *my_addr, socklen_t addrlen)
131 {
132         Dprintf("bind swift socket\n");
133         struct listsockaddr lsa;
134         transformFromSwiftToAddr(&lsa, *my_addr);
135                 
136         return bind(s->socketListener, (const struct sockaddr *)&lsa.sa[0], sizeof(lsa.sa[0]));
137 }
138
139 // Function to create a Swift socket
140 Swift socketSwift(int maxChannels)
141 {
142         Dprintf("create struct swift\n");       
143         Swift s = calloc(1,sizeof(*s));
144
145         Dprintf("create swift socket listener\n");      
146         CHECK(s->socketListener = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
147
148         Dprintf("create swift send channel\n"); 
149         CHECK(s->sendChannel = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
150
151         Dprintf("create swift send channel\n"); 
152         CHECK(s->recvChannel = calloc(100,sizeof(SOCKET)));
153         
154         s->usedChannels = 0;
155         s->maxChannels = maxChannels;
156         
157         return s;
158 }
159
160
161 void closeSwift(Swift s)
162 {
163         Dprintf("close swift socket\n");
164         close(s->socketListener);
165         close(s->sendChannel);
166         
167         
168         free(s);
169 }
170
171