2 #include <linux/list.h>
3 #include <linux/spinlock.h>
7 #include "p2pkp_sock.h"
8 #include "p2pkp_debug.h"
9 #include "p2pkp_file.h"
12 static int p2pkp_release(struct socket *sock);
13 static int p2pkp_bind(struct socket *sock, struct sockaddr *myaddr,
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);
22 /* creates a socket */
23 static int p2pkp_create(struct net *net, struct socket *sock, int protocol,
27 static struct proto p2pkp_proto = {
28 .name = P2PKP_PROTO_NAME,
30 .obj_size = sizeof(struct p2pkp_sock),
33 /* protocol operations */
34 static const struct proto_ops p2pkp_ops = {
37 .release = p2pkp_release,
39 .connect = p2pkp_connect,
40 .sendmsg = p2pkp_sendmsg,
41 .recvmsg = p2pkp_recvmsg,
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,
54 .sendpage = sock_no_sendpage,
59 static const struct net_proto_family p2pkp_family_ops = {
61 .create = p2pkp_create,
67 int p2pkp_register_protocol(void)
71 err = sock_register(&p2pkp_family_ops);
73 ERROR("cannot register operations");
77 err = proto_register(&p2pkp_proto, 0);
79 ERROR("cannot register proto");
82 DEBUG("Successfully registered socket operations");
87 sock_unregister(PF_P2PKP);
93 void p2pkp_unregister_protocol(void)
95 DEBUG("Unregistering protocol");
96 proto_unregister(&p2pkp_proto);
97 sock_unregister(PF_P2PKP);
98 DEBUG("Successfully UNregistered socket operations");
102 static int p2pkp_release(struct socket *sock)
104 struct sock *sk = sock->sk;
105 struct p2pkp_sock *ps = sock2p2pkp(sk);
112 sk->sk_shutdown = SEND_SHUTDOWN;
114 skb_queue_purge(&sk->sk_receive_queue);
115 skb_queue_purge(&sk->sk_write_queue);
116 skb_queue_purge(&sk->sk_error_queue);
118 /* TODO: some statistics, don't know if really
120 //sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
122 /* TODO do whatever is needed with ps */
124 if (!sock_flag(sk, SOCK_DEAD))
125 sk->sk_state_change(sk);
129 sock_set_flag(sk, SOCK_DEAD);
132 p2pkp_destroy_udp_sock(ps->net_sock);
134 p2pkp_close_file(ps->file);
139 DEBUG("Released the socket");
143 static int p2pkp_bind(struct socket *sock, struct sockaddr *myaddr,
146 struct sock *sk = sock->sk;
147 struct p2pkp_sock *ps = sock2p2pkp(sk);
148 struct sockaddr_in *sin = (struct sockaddr_in *)myaddr;
151 if (!sock || !myaddr || sockaddr_len != sizeof(struct sockaddr_in) ||
152 sin->sin_family != AF_INET) {
153 ERROR("invalid parameters for bind");
158 err = ps->net_sock->ops->bind(ps->net_sock, myaddr, sockaddr_len);
160 ERROR("can't bind socket");
167 static int p2pkp_connect(struct socket *sock, struct sockaddr *vaddr,
168 int sockaddr_len, int flags)
170 struct sock *sk = sock->sk;
171 struct p2pkp_sock *ps = sock2p2pkp(sk);
172 struct p2pkp_conn_info *pconn;
174 if (!sk || !vaddr || sockaddr_len != sizeof(struct sockaddr_in) ||
175 vaddr->sa_family != AF_INET) {
176 ERROR("invalid socket parameters");
180 pconn = kmalloc(sizeof(struct p2pkp_conn_info), GFP_KERNEL);
182 ERROR("no more memory for new list element");
186 INIT_LIST_HEAD(&pconn->list);
187 memcpy(&pconn->sin, vaddr, sockaddr_len);
191 /* TODO spinlock required? */
192 list_add(&pconn->list, &ps->conn_list);
194 sock->state = SS_CONNECTED;
197 DEBUG("Connected socket to a peer");
202 static int p2pkp_sendmsg(struct kiocb *iocb, struct socket *sock,
203 struct msghdr *m, size_t total_len)
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;
212 struct list_head *pos;
213 struct p2pkp_conn_info *conn;
216 (sin && sizeof(struct sockaddr_in) != m->msg_namelen)) {
217 ERROR("invalid socket parameters");
221 if (sin && ((err = p2pkp_connect(sock, (struct sockaddr *)sin,
222 sizeof(struct sockaddr_in), 0)) < 0)) {
223 ERROR("cannot connect to socket");
228 if (!(sock->state & SS_CONNECTED)) {
229 ERROR("unconnected socket");
231 return -ECONNREFUSED;
235 /* check if the file exists */
236 for (f_index = 0; f_index < m->msg_iovlen; f_index++) {
238 file_name = (char *)m->msg_iov[f_index].iov_base;
239 file = p2pkp_open_file_read(file_name);
241 ERROR("cannot open file %s\n", file_name);
246 DEBUG("opened file %s", file_name);
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");
259 /* iterate through all the connections to send the data */
260 list_for_each(pos, &ps->conn_list) {
262 conn = list_entry(pos, struct p2pkp_conn_info, list);
263 err = p2pkp_msgsend(ps->net_sock, &conn->sin,
264 ps->buffer, bytes_read);
266 ERROR("can't send first message");
277 p2pkp_close_file(file);
281 DEBUG("Sending completed successfully");
282 return err ? err : files_no;
286 static int p2pkp_recvmsg(struct kiocb *iocb, struct socket *sock,
287 struct msghdr *m, size_t total_len, int flags)
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;
295 char *file_name = (char *)m->msg_iov[0].iov_base;
296 mode_t mode = P2PKP_DEFAULT_MODE;
298 /* first try to get some files */
299 if (!sock || !m || !file_name) {
300 ERROR("invalid socket parameters");
304 file = p2pkp_open_file_write(file_name, mode);
306 ERROR("cannot open file %s\n", file_name);
312 /* TODO keep connections */
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);
318 } else if (bytes_read != -ERESTARTSYS) {
319 ERROR("cannot read data: %d", bytes_read);
322 DEBUG("wrote %d", bytes_written);
323 } while (bytes_read < ps->buffer_len);
326 p2pkp_close_file(file);
329 return err ? err : bytes_written;
333 static int p2pkp_create(struct net *net, struct socket *sock, int protocol,
336 struct sock *sk = NULL;
337 struct p2pkp_sock *ps;
338 int err = -ESOCKTNOSUPPORT;
340 DEBUG("Creating new P2PKP socket");
341 if (sock->type != SOCK_DGRAM) {
342 ERROR("P2PKP supports only SOCK_DGRAM sockets");
346 ERROR("protocol %x not suported - currently only 0 is supported",
351 sock->state = SS_UNCONNECTED;
354 sk = sk_alloc(net, PF_P2PKP, GFP_KERNEL, &p2pkp_proto);
356 ERROR("unable to create new socket");
360 sock->ops = &p2pkp_ops;
361 sock_init_data(sock, sk);
365 sk->sk_family = PF_P2PKP;
366 sk->sk_protocol = protocol;
367 sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
369 /* TODO init further data */
372 err = p2pkp_create_udp_sock(&ps->net_sock);
374 ERROR("cannot create UDP socket");
377 ps->buffer_len = P2PKP_DEFAULT_BUF_LEN;
379 INIT_LIST_HEAD(&ps->conn_list);
380 spin_lock_init(&ps->conn_lock);
382 DEBUG("Created new P2PKP socket");