SYSCALL_DEFINE5 setsockopt 代码流程

本文深入探讨了Linux系统中socket选项的设置过程,包括setsockopt函数的实现细节,以及TCP和IP选项的处理流程。通过分析内核源码,解释了如何为套接字设置不同级别的选项,并展示了socket选项的安全性和功能性验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
        char __user *, optval, int, optlen)
{
    int err, fput_needed;
    struct socket *sock;

    if (optlen < 0)
        return -EINVAL;

    sock = sockfd_lookup_light(fd, &err, &fput_needed);
    if (sock != NULL) {
        err = security_socket_setsockopt(sock, level, optname);
        if (err)
            goto out_put;

        if (level == SOL_SOCKET)
            err =
                sock_setsockopt(sock, level, optname, optval,
                        optlen);
        else
            err =
                sock->ops->setsockopt(sock, level, optname, optval,
                          optlen);
out_put:
        fput_light(sock->file, fput_needed);
    }
    return err;
}


const struct proto_ops inet_stream_ops = {
    .family           = PF_INET,
    .owner           = THIS_MODULE,
    .release       = inet_release,
    .bind           = inet_bind,
    .connect       = inet_stream_connect,
    .socketpair       = sock_no_socketpair,
    .accept           = inet_accept,
    .getname       = inet_getname,
    .poll           = tcp_poll,
    .ioctl           = inet_ioctl,
    .listen           = inet_listen,
    .shutdown       = inet_shutdown,
    .setsockopt       = sock_common_setsockopt,
    .getsockopt       = sock_common_getsockopt,
    

    err = -ENOBUFS;
    sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);
    if (sk == NULL)
        goto out;    
    

    /*
 *    Set socket options on an inet socket.
 */
int sock_common_setsockopt(struct socket *sock, int level, int optname,
               char __user *optval, unsigned int optlen)
{
    struct sock *sk = sock->sk;

    //call tcp_prot setsockopt api
    return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
}


int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
           unsigned int optlen)
{
    const struct inet_connection_sock *icsk = inet_csk(sk);

    //IP option handler
    if (level != SOL_TCP)
        return icsk->icsk_af_ops->setsockopt(sk, level, optname,
                             optval, optlen);
                             
    //TCP option handler
    return do_tcp_setsockopt(sk, level, optname, optval, optlen);
}
EXPORT_SYMBOL(tcp_setsockopt);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值