X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=blobdiff_plain;f=module%2Fp2pkp_sock.c;h=19d29d54884b872a7b33ded5d868a62866a4a298;hb=71246fb0c8dead16cc33caf83020961c33f8efda;hp=d72fdb3caaee96208d02768f473fcf3180253432;hpb=2d6f09bf6e183a2a889d52af3c0acc48c5998043;p=p2p-kernel-protocol.git diff --git a/module/p2pkp_sock.c b/module/p2pkp_sock.c index d72fdb3..19d29d5 100644 --- a/module/p2pkp_sock.c +++ b/module/p2pkp_sock.c @@ -130,6 +130,10 @@ static int p2pkp_release(struct socket *sock) sock->sk = NULL; p2pkp_destroy_udp_sock(ps->net_sock); + if (ps->file) { + p2pkp_close_file(ps->file); + ps->file = 0; + } sock_put(sk); DEBUG("Released the socket"); @@ -137,8 +141,28 @@ static int p2pkp_release(struct socket *sock) } static int p2pkp_bind(struct socket *sock, struct sockaddr *myaddr, - int sockaddr_len){return 0;} + int sockaddr_len) +{ + struct sock *sk = sock->sk; + struct p2pkp_sock *ps = sock2p2pkp(sk); + struct sockaddr_in *sin = (struct sockaddr_in *)myaddr; + int err = 0; + + if (!sock || !myaddr || sockaddr_len != sizeof(struct sockaddr_in) || + sin->sin_family != AF_INET) { + ERROR("invalid parameters for bind"); + return -EINVAL; + } + + lock_sock(sk); + err = ps->net_sock->ops->bind(ps->net_sock, myaddr, sockaddr_len); + if (err < 0) { + ERROR("can't bind socket"); + } + release_sock(sk); + return err; +} static int p2pkp_connect(struct socket *sock, struct sockaddr *vaddr, int sockaddr_len, int flags) @@ -178,8 +202,8 @@ static int p2pkp_connect(struct socket *sock, struct sockaddr *vaddr, static int p2pkp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len) { - int err = -ENXIO; - int f_index, bytes_read; + int err = 0; + int f_index, bytes_read, files_no = 0; struct sock *sk = sock->sk; struct p2pkp_sock *ps = sock2p2pkp(sk); struct sockaddr_in *sin = (struct sockaddr_in *)m->msg_name; @@ -203,25 +227,29 @@ static int p2pkp_sendmsg(struct kiocb *iocb, struct socket *sock, lock_sock(sk); if (!(sock->state & SS_CONNECTED)) { ERROR("unconnected socket"); - err = -ECONNREFUSED; - goto release; + release_sock(sk); + return -ECONNREFUSED; } release_sock(sk); /* check if the file exists */ for (f_index = 0; f_index < m->msg_iovlen; f_index++) { + err = 0; file_name = (char *)m->msg_iov[f_index].iov_base; file = p2pkp_open_file_read(file_name); if (!file) { ERROR("cannot open file %s\n", file_name); + err = -ENOENT; continue; } + ps->file = file; DEBUG("opened file %s", file_name); for (;;) { bytes_read = p2pkp_read_from_file(file, ps->buffer, ps->buffer_len); DEBUG("read %d bytes from file", bytes_read); if (bytes_read < 0) { ERROR("cannot read from file"); + err = bytes_read; goto out_close; } if (bytes_read == 0) @@ -232,13 +260,14 @@ static int p2pkp_sendmsg(struct kiocb *iocb, struct socket *sock, list_for_each(pos, &ps->conn_list) { conn = list_entry(pos, struct p2pkp_conn_info, list); - err = p2pkp_msgsend(ps->net_sock, - &conn->sin, ps->buffer, ps->buffer_len); + err = p2pkp_msgsend(ps->net_sock, &conn->sin, + ps->buffer, bytes_read); if (err < 0) { ERROR("can't send first message"); goto out_conn; } } + files_no++; out_conn: release_sock(sk); } @@ -246,19 +275,59 @@ out_conn: out_close: p2pkp_close_file(file); + ps->file = 0; } - DEBUG("Sending completed successfully"); - err = 0; -release: - release_sock(sk); - return err; + return err ? err : files_no; } static int p2pkp_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *m, size_t total_len, int flags){return 0;} + struct msghdr *m, size_t total_len, int flags) +{ + int err = -ENXIO; + int bytes_read, bytes_written = 0; + struct sock *sk = sock->sk; + struct p2pkp_sock *ps = sock2p2pkp(sk); + struct sockaddr_in *sin = (struct sockaddr_in *)m->msg_name; + struct file * file; + char *file_name = (char *)m->msg_iov[0].iov_base; + mode_t mode = P2PKP_DEFAULT_MODE; + + /* first try to get some files */ + if (!sock || !m || !file_name) { + ERROR("invalid socket parameters"); + return -EINVAL; + } + + file = p2pkp_open_file_write(file_name, mode); + if (!file) { + ERROR("cannot open file %s\n", file_name); + return -ENOENT; + } + ps->file = file; + + lock_sock(sk); + /* TODO keep connections */ + do { + bytes_read = p2pkp_msgrecv(ps->net_sock, sin, ps->buffer, ps->buffer_len); + if (bytes_read > 0) { + bytes_written += p2pkp_write_in_file(file, ps->buffer, bytes_read); + err = 0; + } else if (bytes_read != -ERESTARTSYS) { + ERROR("cannot read data: %d", bytes_read); + err = -ENXIO; + } + DEBUG("wrote %d", bytes_written); + } while (bytes_read < ps->buffer_len); + + release_sock(sk); + p2pkp_close_file(file); + ps->file = 0; + + return err ? err : bytes_written; +} static int p2pkp_create(struct net *net, struct socket *sock, int protocol, @@ -318,5 +387,3 @@ error: sock_put(sk); return err; } - -