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