static int threadfn(void *data) { struct socket *sock; struct sockaddr_in addr; int size,i; char buf[bufsize+1]; if (sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock) < 0) { err("sock_create_kern"); goto out; } sock->sk->sk_reuse = 1; memset(&addr, '\0', sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(9734); if (kernel_bind(sock, &addr, sizeof(addr)) < 0) { err("kernel_bind"); goto err; } if (kernel_listen(sock, 1024) < 0) { err("kernel_listen"); goto err; } while (!kthread_should_stop()) { struct socket *newsock; struct inet_connection_sock *icsk = inet_csk(sock->sk); struct socket_wq *wq; rcu_read_lock(); wq = rcu_dereference(sock->sk->sk_wq); wait_event_interruptible(wq->wait,!reqsk_queue_empty(&icsk->icsk_accept_queue) || kthread_should_stop()); if (!reqsk_queue_empty(&icsk->icsk_accept_queue)) { if (kernel_accept(sock, &newsock, MSG_WAITALL) != 0) { err("kernel_accept"); goto err; } printk(KERN_INFO "Server : accept a new connection request.\n"); // transfer_data(newsock); memset(&buf, 0, bufsize+1); size = receive(newsock, buf, bufsize/2); printk(KERN_INFO "Server : received %d bytes\n", size); //data processing printk("Server : received data: %s\n", buf); size = receive(newsock, buf, bufsize/2); if (size < 0) { printk(KERN_INFO ": error getting datagram, sock_recvmsg error = %d\n", size); break; } else { printk(KERN_INFO "Server : received %d bytes\n", size); //data processing printk("Server : received data: %s\n", buf); for( i=0;i<bufsize/2;i++) { buf[i]+=1; } buf[i]=0 ; // sending //printk("buf=%s\n",buf); size=send(newsock, buf, bufsize/2+1); if(size<0) printk("Server : error send\n"); } //printk("ch =%c\n",ch); sock_release(newsock); } } err: sock_release(sock); out: return 0; }
//start_listening void moon_listen(void) { //For test purposes moonraker_socket_t *listen; listen = kmalloc(sizeof(moonraker_socket_t),GFP_KERNEL); listen->proto = kmalloc(sizeof(moonraker_proto_t),GFP_KERNEL); listen->proto->name = kmalloc(5,GFP_KERNEL); listen->ip = 2130706433; listen->port = 80; listen->proto->defer_accept=0; listen->keepalive_timeout=0; listen->ack_pingpong=1; listen->max_backlog=2048; listen->defer_accept=1; strcpy(listen->proto->name,"http"); //end for test purpose struct sockaddr_in sin; struct socket *sock = NULL; struct sock *sk; struct tcp_sock *tp; struct inet_connection_sock *icsk; moonraker_proto_t *proto = listen->proto; u16 port = listen->port; u32 addr = listen->ip; //127.0.0.1 int err = 0; err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); if (err) { printk(KERN_ERR "Moonraker: error %d creating socket.\n", err); goto error; } sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(addr); sin.sin_port = htons(port); sk = sock->sk; icsk = inet_csk(sk); sk->sk_reuse = 1; sock_set_flag(sk, SOCK_URGINLINE); err = sock->ops->bind(sock, (struct sockaddr*)&sin, sizeof(sin)); if (err){ printk(KERN_ERR "Moonraker: error %d binding socket. This means that probably some other process is (or was a short time ago) using addr %d\n",err,sin.sin_addr.s_addr); goto error; } tp = tcp_sk(sk); printk("listen sk accept_queue: %d.\n",!reqsk_queue_empty(&icsk->icsk_accept_queue)); icsk->icsk_ack.pingpong = listen->ack_pingpong; sock_reset_flag(sk, SOCK_LINGER); sk->sk_lingertime = 0; tp->linger2 = listen->keepalive_timeout * HZ; if (proto->defer_accept && !listen->keepalive_timeout && listen->defer_accept) icsk->icsk_accept_queue.rskq_defer_accept = 1; err = sock->ops->listen(sock, listen->max_backlog); if (err) { printk(KERN_ERR "Moonraker: error %d listening on socket.\n", err); goto error; } printk(KERN_NOTICE "Moonraker: thread %d listens on %s://%d.%d.%d.%d:%d.\n", 1, proto->name, HIPQUAD(addr), port); // return sock; return; error: if (sock) sock_release(sock); return; return NULL; }