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