lkml.org 
[lkml]   [2000]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectTCP 'data_ready' callback is broken ?
Hi,

while developing kernel module that should use sock callback 'data_ready'
I have found that for the TCP socket it is never called.

I am totally confused at this point and would appreciate any help or hints
or whatever. Please note, that if I try to use this callback for UDP
socket everything is perfect ( like it is in RPC subsystem ).

I attach sample module that can be used to reproduce the problem:

yellow# gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -c mod.c
yellow# cat >> /etc/inetd.conf
565 stream tcp nowait root /usr/bin/yes yes
^D
yellow# insmod ./mod.o
yellow# netstat -av
......................
tcp 32686 0 localhost:1025 localhost:565 ESTABLISHED
tcp 0 62824 localhost:565 localhost:1025 ESTABLISHED
.......................
yellow# tail /var/log/messages

Mar 20 00:35:56 yellow kernel: write_space callback
Mar 20 00:35:56 yellow kernel: write_space callback
Mar 20 00:35:56 yellow kernel: state_change callback
Mar 20 00:35:56 yellow kernel: write_space callback
Mar 20 00:35:56 yellow last message repeated 14 times
Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message
Mar 20 00:35:56 yellow kernel: 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message
Mar 20 00:35:56 yellow kernel: 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message
Mar 20 00:35:56 yellow kernel: 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message
Mar 20 00:35:56 yellow kernel: 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message y 1 bytes long
Mar 20 00:35:56 yellow kernel: Receiving message
Mar 20 00:35:56 yellow kernel: 1 bytes long
Mar 20 00:35:56 yellow kernel: write_space callback

As you can see 'data_ready' is never called.

Thanks,
Roman.
#include <linux/config.h>
#include <linux/module.h>

#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/locks.h>
#include <linux/unistd.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/lockd/bind.h>

#include <linux/socket.h>
#include <linux/in.h>
#include <linux/net.h>
#include <linux/udp.h>
#include <net/sock.h>
#include <net/checksum.h>
#include <net/udp.h>

#include <asm/system.h>
#include <asm/uaccess.h>


static void mod_data_ready(struct sock *sk, int len)
{
printk("data_ready callback\n");
}

static void mod_state_change(struct sock *sk)
{
printk("state_change callback\n");
}

static void mod_write_space(struct sock *sk)
{
printk("write_space callback\n");
}


static struct socket *sock;

static inline int
mod_rcv_msg()
{
unsigned char buf[4];

struct msghdr msg;
mm_segment_t oldfs;
int result;
struct iovec iov;

iov.iov_base = &buf[0];
iov.iov_len = 1;

msg.msg_flags = MSG_DONTWAIT;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;

oldfs = get_fs(); set_fs(get_ds());
result = sock_recvmsg(sock, &msg, 1, MSG_DONTWAIT);
set_fs(oldfs);

printk("Receiving message %c %d bytes long\n", buf[0], result);
return result;
}


int
init_module(void)
{
struct sockaddr_in sap;
int err;
int i;

sap.sin_family = AF_INET;
sap.sin_port = 13570;
sap.sin_addr.s_addr = 16777343;

if ((err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
printk("can't create socket (%d).\n", -err);
return -1;
}

sock->sk->data_ready = mod_data_ready;
sock->sk->state_change = mod_state_change;
sock->sk->write_space = mod_write_space;

err = sock->ops->connect(sock, (struct sockaddr *) &sap,
sizeof(struct sockaddr_in), 0);

if (err < 0) {
sock_release(sock);
printk("TCP connect failed (%d).\n", -err);
return -1;
}


for (i=0;i<10;i++)
mod_rcv_msg();

return 0;
}

void
cleanup_module(void)
{
sock_release(sock);
}
\
 
 \ /
  Last update: 2005-03-22 13:57    [W:0.102 / U:0.000 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site