module: added support for multiple USERSPACE receivers
[p2p-kernel-protocol.git] / module / p2pkp_sock.c
1 #include <linux/net.h>
2 #include <linux/list.h>
3 #include <linux/spinlock.h>
4
5 #include "p2pkp.h"
6 #include "p2pkp_net.h"
7 #include "p2pkp_sock.h"
8 #include "p2pkp_debug.h"
9 #include "p2pkp_file.h"
10
11
12 static int p2pkp_release(struct socket *sock);
13 static int p2pkp_bind(struct socket *sock, struct sockaddr *myaddr,
14                 int sockaddr_len);
15 static int p2pkp_connect(struct socket *sock, struct sockaddr *vaddr,
16                 int sockaddr_len, int flags);
17 static int p2pkp_sendmsg(struct kiocb *iocb, struct socket *sock,
18                 struct msghdr *m, size_t total_len);
19 static int p2pkp_recvmsg(struct kiocb *iocb, struct socket *sock,
20                 struct msghdr *m, size_t total_len, int flags);
21
22 /* creates a socket */
23 static int p2pkp_create(struct net *net, struct socket *sock, int protocol,
24                 int kern);
25
26 /* protocol */
27 static struct proto p2pkp_proto = {
28         .name           = P2PKP_PROTO_NAME,
29         .owner          = THIS_MODULE,
30         .obj_size       = sizeof(struct p2pkp_sock),
31 };
32
33 /* protocol operations */
34 static const struct proto_ops p2pkp_ops = {
35         .family         = PF_P2PKP,
36         .owner          = THIS_MODULE,
37         .release        = p2pkp_release,
38         .bind           = p2pkp_bind,
39         .connect        = p2pkp_connect,
40         .sendmsg        = p2pkp_sendmsg,
41         .recvmsg        = p2pkp_recvmsg,
42
43         /* unimplemented */
44         .poll           = datagram_poll,
45         .socketpair     = sock_no_socketpair,
46         .accept         = sock_no_accept,
47         .getname        = sock_no_getname,
48         .ioctl          = sock_no_ioctl,
49         .listen         = sock_no_listen,
50         .shutdown       = sock_no_shutdown,
51         .setsockopt     = sock_no_setsockopt,
52         .getsockopt     = sock_no_getsockopt,
53         .mmap           = sock_no_mmap,
54         .sendpage       = sock_no_sendpage,
55 };
56
57
58 /* family socket */
59 static const struct net_proto_family p2pkp_family_ops = {
60         .family         = PF_P2PKP,
61         .create         = p2pkp_create,
62         .owner          = THIS_MODULE,
63 };
64
65
66
67 int p2pkp_register_protocol(void)
68 {
69         int err;
70
71         err = sock_register(&p2pkp_family_ops);
72         if (err) {
73                 ERROR("cannot register operations");
74                 goto exit;
75         }
76
77         err = proto_register(&p2pkp_proto, 0);
78         if (err) {
79                 ERROR("cannot register proto");
80                 goto sock_unreg;
81         }
82         DEBUG("Successfully registered socket operations");
83
84         return 0;
85
86 sock_unreg:
87         sock_unregister(PF_P2PKP);
88 exit:
89         return err;
90
91 }
92
93 void p2pkp_unregister_protocol(void)
94 {
95         DEBUG("Unregistering protocol");
96         proto_unregister(&p2pkp_proto);
97         sock_unregister(PF_P2PKP);
98         DEBUG("Successfully UNregistered socket operations");
99 }
100
101
102 static int p2pkp_release(struct socket *sock)
103 {
104         struct sock *sk = sock->sk;
105         struct p2pkp_sock *ps = sock2p2pkp(sk);
106
107         if (!sk)
108                 return 0;
109
110         lock_sock(sk);
111         sock_orphan(sk);
112         sk->sk_shutdown = SEND_SHUTDOWN;
113
114         skb_queue_purge(&sk->sk_receive_queue);
115         skb_queue_purge(&sk->sk_write_queue);
116         skb_queue_purge(&sk->sk_error_queue);
117
118         /* TODO: some statistics, don't know if really
119          * needed */
120         //sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
121
122         /* TODO do whatever is needed with ps */
123
124         if (!sock_flag(sk, SOCK_DEAD))
125                 sk->sk_state_change(sk);
126
127         release_sock(sk);
128
129         sock_set_flag(sk, SOCK_DEAD);
130         sock->sk = NULL;
131
132         p2pkp_destroy_udp_sock(ps->net_sock);
133         
134         sock_put(sk);
135         DEBUG("Released the socket");
136         return 0;
137 }
138
139 static int p2pkp_bind(struct socket *sock, struct sockaddr *myaddr,
140                 int sockaddr_len){return 0;}
141
142
143 static int p2pkp_connect(struct socket *sock, struct sockaddr *vaddr,
144                 int sockaddr_len, int flags)
145 {
146         struct sock *sk = sock->sk;
147         struct p2pkp_sock *ps = sock2p2pkp(sk);
148         struct p2pkp_conn_info *pconn;
149
150         if (!sk || !vaddr || sockaddr_len != sizeof(struct sockaddr_in) ||
151                         vaddr->sa_family != AF_INET) {
152                 ERROR("invalid socket parameters");
153                 return -EINVAL;
154         }
155
156         pconn = kmalloc(sizeof(struct p2pkp_conn_info), GFP_KERNEL);
157         if (!pconn) {
158                 ERROR("no more memory for new list element");
159                 return -ENOMEM;
160         }
161
162         INIT_LIST_HEAD(&pconn->list);
163         memcpy(&pconn->sin, vaddr, sockaddr_len);
164
165         lock_sock(sk);
166
167         /* TODO spinlock required? */
168         list_add(&pconn->list, &ps->conn_list);
169
170         sock->state = SS_CONNECTED;
171         release_sock(sk);
172
173         DEBUG("Connected socket to a peer");
174
175         return 0;
176 }
177
178 static int p2pkp_sendmsg(struct kiocb *iocb, struct socket *sock,
179                 struct msghdr *m, size_t total_len)
180 {
181         int err = -ENXIO;
182         int f_index, bytes_read;
183         struct sock *sk = sock->sk;
184         struct p2pkp_sock *ps = sock2p2pkp(sk);
185         struct sockaddr_in *sin = (struct sockaddr_in *)m->msg_name;
186         struct file * file;
187         char *file_name;
188         struct list_head *pos;
189         struct p2pkp_conn_info *conn;
190
191         if (!sk || !sock ||
192                         (sin && sizeof(struct sockaddr_in) != m->msg_namelen)) {
193                 ERROR("invalid socket parameters");
194                 return -EINVAL;
195         }
196
197         if (sin && ((err = p2pkp_connect(sock, (struct sockaddr *)sin,
198                                                 sizeof(struct sockaddr_in), 0)) < 0)) {
199                 ERROR("cannot connect to socket");
200                 return err;
201         }
202
203         lock_sock(sk);
204         if (!(sock->state & SS_CONNECTED)) {
205                 ERROR("unconnected socket");
206                 err = -ECONNREFUSED;
207                 goto release;
208         }
209         release_sock(sk);
210
211         /* check if the file exists */
212         for (f_index = 0; f_index < m->msg_iovlen; f_index++) {
213                 file_name = (char *)m->msg_iov[f_index].iov_base;
214                 file = p2pkp_open_file_read(file_name);
215                 if (!file) {
216                         ERROR("cannot open file %s\n", file_name);
217                         continue;
218                 }
219                 DEBUG("opened file %s", file_name);
220                 for (;;) {
221                         bytes_read = p2pkp_read_from_file(file, ps->buffer, ps->buffer_len);
222                         DEBUG("read %d bytes from file", bytes_read);
223                         if (bytes_read < 0) {
224                                 ERROR("cannot read from file");
225                                 goto out_close;
226                         }
227                         if (bytes_read == 0)
228                                 goto out_close;
229
230                         lock_sock(sk);
231                         /* iterate through all the connections to send the data */
232                         list_for_each(pos, &ps->conn_list) {
233                                         
234                                 conn = list_entry(pos, struct p2pkp_conn_info, list);
235                                 err = p2pkp_msgsend(ps->net_sock,
236                                                 &conn->sin, ps->buffer, ps->buffer_len);
237                                 if (err < 0) {
238                                         ERROR("can't send first message");
239                                         goto out_conn;
240                                 }
241                         }
242 out_conn:
243                         release_sock(sk);
244                 }
245
246 out_close:
247
248                 p2pkp_close_file(file);
249         }
250
251
252         DEBUG("Sending completed successfully");
253         err = 0;
254 release:
255         release_sock(sk);
256         return err;
257 }
258
259
260 static int p2pkp_recvmsg(struct kiocb *iocb, struct socket *sock,
261                 struct msghdr *m, size_t total_len, int flags){return 0;}
262
263
264 static int p2pkp_create(struct net *net, struct socket *sock, int protocol,
265                 int kern)
266 {
267         struct sock *sk = NULL;
268         struct p2pkp_sock *ps;
269         int err = -ESOCKTNOSUPPORT;
270
271         DEBUG("Creating new P2PKP socket");
272         if (sock->type != SOCK_DGRAM) {
273                 ERROR("P2PKP supports only SOCK_DGRAM sockets");
274                 goto error;
275         }
276         if (protocol) {
277                 ERROR("protocol %x not suported - currently only 0 is supported",
278                                 protocol);
279                 goto error;
280         }
281
282         sock->state = SS_UNCONNECTED;
283
284         err = -ENOBUFS;
285         sk = sk_alloc(net, PF_P2PKP, GFP_KERNEL, &p2pkp_proto);
286         if (unlikely(!sk)) {
287                 ERROR("unable to create new socket");
288                 goto error;
289         }
290
291         sock->ops = &p2pkp_ops;
292         sock_init_data(sock, sk);
293
294         sk->sk_reuse = 1;
295         sk->sk_no_check = 1;
296         sk->sk_family = PF_P2PKP;
297         sk->sk_protocol = protocol;
298         sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
299
300         /* TODO init further data */
301         ps = sock2p2pkp(sk);
302
303         err = p2pkp_create_udp_sock(&ps->net_sock);
304         if (err < 0) {
305                 ERROR("cannot create UDP socket");
306                 goto error;
307         }
308         ps->buffer_len = P2PKP_DEFAULT_BUF_LEN;
309
310         INIT_LIST_HEAD(&ps->conn_list);
311         spin_lock_init(&ps->conn_lock);
312
313         DEBUG("Created new P2PKP socket");
314
315         return 0;
316 error:
317         if (sk)
318                 sock_put(sk);
319         return err;
320 }
321
322