UDP 데이터 수신에 대한 질문입니다.

kim1158의 이미지

udp는 비연결지향이므로 패킷이 도착하면
네트웍,ip층을거쳐 소켓버퍼(sk_buff)를 만들고 tcp와는 다르게 프로세스를 wakeup하지않고 해당프로세스가 값을 받아갈때까지 소켓버퍼에 저장해두는것으로 알고있습니다.

질문은요.
1)해당UDP패킷을 받는 프로세스가 도착한 데이터가 있나 체크하는 시점이 언제인가요?
아마도 스케줄링되서 실행상태로 진입하게 될때라는 생각이 들긴하는데요.

2)sk_buff 수신큐도 버퍼크기 제한이 있을것 같은데요.
크기제한이 얼만큼인지. 버퍼에두고 언제까지 UDP에서 가져가길 기다리는지.

조언을 듣고싶습니다.

jhanglim의 이미지

^_______^

제가 엄청난 실수를 저질렀군요 ㅎㅎ
정말 죄송합니다.

pastime의 이미지

심심해서? 커널 소스 (2.4.20) 을 보면서 따라가 보았습니다.. 8)

간략하게 정리해보면

 <~/net/ipv4/udp.c> 에서
int udp_rcv(struct sk_buff *skb)
{
    struct sock *sk;

    sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex);

    if (sk != NULL) {
        udp_queue_rcv_skb(sk, skb);
        sock_put(sk);
        return 0;
    }

}

 <~/net/ipv4/udp.c> 에서
static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
{
    if (sock_queue_rcv_skb(sk,skb)<0) {
        kfree_skb(skb);
        return -1;
    }

    return 0;
}

 <~/include/net/sock.h> 에서
static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
    skb_queue_tail(&sk->receive_queue, skb);

    if (!sk->dead)
        sk->data_ready(sk,skb->len);

    return 0;
}

여기서 sk->data_ready 는 sock_def_readable 을 가리키므로

따라가 보면 wakeup 코드가 나옵니다.. :D

 <~/net/core/sock.c> 에서
void sock_def_readable(struct sock *sk, int len)
{
    read_lock(&sk->callback_lock);

    if (sk->sleep && waitqueue_active(sk->sleep))
        wake_up_interruptible(sk->sleep);

    sk_wake_async(sk,1,POLL_IN);
    read_unlock(&sk->callback_lock);
}