module: fixed receiving size
[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         if (ps->file) {
134                 p2pkp_close_file(ps->file);
135                 ps->file = 0;
136         }
137         
138         sock_put(sk);
139         DEBUG("Released the socket");
140         return 0;
141 }
142
143 static int p2pkp_bind(struct socket *sock, struct sockaddr *myaddr,
144                 int sockaddr_len)
145 {
146         struct sock *sk = sock->sk;
147         struct p2pkp_sock *ps = sock2p2pkp(sk);
148         struct sockaddr_in *sin = (struct sockaddr_in *)myaddr;
149         int err = 0;
150
151         if (!sock || !myaddr || sockaddr_len != sizeof(struct sockaddr_in) ||
152                         sin->sin_family != AF_INET) {
153                 ERROR("invalid parameters for bind");
154                 return -EINVAL;
155         }
156
157         lock_sock(sk);
158         err = ps->net_sock->ops->bind(ps->net_sock, myaddr, sockaddr_len);
159         if (err < 0) {
160                 ERROR("can't bind socket");
161         }
162         release_sock(sk);
163
164         return err;
165 }
166
167 static int p2pkp_connect(struct socket *sock, struct sockaddr *vaddr,
168                 int sockaddr_len, int flags)
169 {
170         struct sock *sk = sock->sk;
171         struct p2pkp_sock *ps = sock2p2pkp(sk);
172         struct p2pkp_conn_info *pconn;
173
174         if (!sk || !vaddr || sockaddr_len != sizeof(struct sockaddr_in) ||
175                         vaddr->sa_family != AF_INET) {
176                 ERROR("invalid socket parameters");
177                 return -EINVAL;
178         }
179
180         pconn = kmalloc(sizeof(struct p2pkp_conn_info), GFP_KERNEL);
181         if (!pconn) {
182                 ERROR("no more memory for new list element");
183                 return -ENOMEM;
184         }
185
186         INIT_LIST_HEAD(&pconn->list);
187         memcpy(&pconn->sin, vaddr, sockaddr_len);
188
189         lock_sock(sk);
190
191         /* TODO spinlock required? */
192         list_add(&pconn->list, &ps->conn_list);
193
194         sock->state = SS_CONNECTED;
195         release_sock(sk);
196
197         DEBUG("Connected socket to a peer");
198
199         return 0;
200 }
201
202 static int p2pkp_sendmsg(struct kiocb *iocb, struct socket *sock,
203                 struct msghdr *m, size_t total_len)
204 {
205         int err = 0;
206         int f_index, bytes_read, files_no = 0;
207         struct sock *sk = sock->sk;
208         struct p2pkp_sock *ps = sock2p2pkp(sk);
209         struct sockaddr_in *sin = (struct sockaddr_in *)m->msg_name;
210         struct file * file;
211         char *file_name;
212         struct list_head *pos;
213         struct p2pkp_conn_info *conn;
214
215         if (!sk || !sock ||
216                         (sin && sizeof(struct sockaddr_in) != m->msg_namelen)) {
217                 ERROR("invalid socket parameters");
218                 return -EINVAL;
219         }
220
221         if (sin && ((err = p2pkp_connect(sock, (struct sockaddr *)sin,
222                                                 sizeof(struct sockaddr_in), 0)) < 0)) {
223                 ERROR("cannot connect to socket");
224                 return err;
225         }
226
227         lock_sock(sk);
228         if (!(sock->state & SS_CONNECTED)) {
229                 ERROR("unconnected socket");
230                 release_sock(sk);
231                 return -ECONNREFUSED;
232         }
233         release_sock(sk);
234
235         /* check if the file exists */
236         for (f_index = 0; f_index < m->msg_iovlen; f_index++) {
237                 err = 0;
238                 file_name = (char *)m->msg_iov[f_index].iov_base;
239                 file = p2pkp_open_file_read(file_name);
240                 if (!file) {
241                         ERROR("cannot open file %s\n", file_name);
242                         err = -ENOENT;
243                         continue;
244                 }
245                 ps->file = file;
246                 DEBUG("opened file %s", file_name);
247                 for (;;) {
248                         bytes_read = p2pkp_read_from_file(file, ps->buffer, ps->buffer_len);
249                         DEBUG("read %d bytes from file", bytes_read);
250                         if (bytes_read < 0) {
251                                 ERROR("cannot read from file");
252                                 err = bytes_read;
253                                 goto out_close;
254                         }
255                         if (bytes_read == 0)
256                                 goto out_close;
257
258                         lock_sock(sk);
259                         /* iterate through all the connections to send the data */
260                         list_for_each(pos, &ps->conn_list) {
261                                         
262                                 conn = list_entry(pos, struct p2pkp_conn_info, list);
263                                 err = p2pkp_msgsend(ps->net_sock, &conn->sin,
264                                                 ps->buffer, bytes_read);
265                                 if (err < 0) {
266                                         ERROR("can't send first message");
267                                         goto out_conn;
268                                 }
269                         }
270                         files_no++;
271 out_conn:
272                         release_sock(sk);
273                 }
274
275 out_close:
276
277                 p2pkp_close_file(file);
278                 ps->file = 0;
279         }
280
281         DEBUG("Sending completed successfully");
282         return err ? err : files_no;
283 }
284
285
286 static int p2pkp_recvmsg(struct kiocb *iocb, struct socket *sock,
287                 struct msghdr *m, size_t total_len, int flags)
288 {
289         int err = -ENXIO;
290         int bytes_read, bytes_written = 0;
291         struct sock *sk = sock->sk;
292         struct p2pkp_sock *ps = sock2p2pkp(sk);
293         struct sockaddr_in *sin = (struct sockaddr_in *)m->msg_name;
294         struct file * file;
295         char *file_name = (char *)m->msg_iov[0].iov_base;
296         mode_t mode = P2PKP_DEFAULT_MODE;
297
298         /* first try to get some files */
299         if (!sock || !m || !file_name) {
300                 ERROR("invalid socket parameters");
301                 return -EINVAL;
302         }
303
304         file = p2pkp_open_file_write(file_name, mode);
305         if (!file) {
306                 ERROR("cannot open file %s\n", file_name);
307                 return -ENOENT;
308         }
309         ps->file = file;
310
311         lock_sock(sk);
312         /* TODO keep connections */
313         do {
314                 bytes_read = p2pkp_msgrecv(ps->net_sock, sin, ps->buffer, ps->buffer_len);
315                 if (bytes_read > 0) {
316                         bytes_written += p2pkp_write_in_file(file, ps->buffer, bytes_read);
317                         err = 0;
318                 } else if (bytes_read != -ERESTARTSYS) {
319                         ERROR("cannot read data: %d", bytes_read);
320                         err = -ENXIO;
321                 }
322                 DEBUG("wrote %d", bytes_written);
323         } while (bytes_read < ps->buffer_len);
324
325         release_sock(sk);
326         p2pkp_close_file(file);
327         ps->file = 0;
328
329         return err ? err : bytes_written;
330 }
331
332
333 static int p2pkp_create(struct net *net, struct socket *sock, int protocol,
334                 int kern)
335 {
336         struct sock *sk = NULL;
337         struct p2pkp_sock *ps;
338         int err = -ESOCKTNOSUPPORT;
339
340         DEBUG("Creating new P2PKP socket");
341         if (sock->type != SOCK_DGRAM) {
342                 ERROR("P2PKP supports only SOCK_DGRAM sockets");
343                 goto error;
344         }
345         if (protocol) {
346                 ERROR("protocol %x not suported - currently only 0 is supported",
347                                 protocol);
348                 goto error;
349         }
350
351         sock->state = SS_UNCONNECTED;
352
353         err = -ENOBUFS;
354         sk = sk_alloc(net, PF_P2PKP, GFP_KERNEL, &p2pkp_proto);
355         if (unlikely(!sk)) {
356                 ERROR("unable to create new socket");
357                 goto error;
358         }
359
360         sock->ops = &p2pkp_ops;
361         sock_init_data(sock, sk);
362
363         sk->sk_reuse = 1;
364         sk->sk_no_check = 1;
365         sk->sk_family = PF_P2PKP;
366         sk->sk_protocol = protocol;
367         sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
368
369         /* TODO init further data */
370         ps = sock2p2pkp(sk);
371
372         err = p2pkp_create_udp_sock(&ps->net_sock);
373         if (err < 0) {
374                 ERROR("cannot create UDP socket");
375                 goto error;
376         }
377         ps->buffer_len = P2PKP_DEFAULT_BUF_LEN;
378
379         INIT_LIST_HEAD(&ps->conn_list);
380         spin_lock_init(&ps->conn_lock);
381
382         DEBUG("Created new P2PKP socket");
383
384         return 0;
385 error:
386         if (sk)
387                 sock_put(sk);
388         return err;
389 }