应用层
NAME
getsockopt - get options on sockets
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
调用关系
函数的调用关系图如下:
数据结构
-
struct tcp_sock {
-
...
-
u32 mss_cache;
-
u8 nonagle : 4,
-
thin_lto : 1,
-
thin_dupack : 1,
-
unused : 2;
-
unsigned int keepalive_time;
-
unsigned int keepalive_intvl;
-
u8 keepalive_probes;
-
int linger2;
-
u8 ecn_flags;
-
u32 rcv_tstamp;
-
u32 lsndtime;
-
-
u32 window_clamp;
-
u32 rcv_ssthresh;
-
-
u16 advmss;
-
u32 total_retrans;
-
...
-
}
-
struct tcp_options_received {
-
...
-
u16 saw_tstamp : 1,
-
tstamp_ok : 1,
-
dsack : 1,
-
wscale_ok : 1,
-
sack_ok : 4,
-
snd_wscale : 4,
-
rcv_wscale : 4,
-
...
-
}
-
-
#define TCPI_OPT_TIMESTAMPS 1
-
#define TCPI_OPT_SACK 2
-
#define TCPI_OPT_WSCALE 4
-
#define TCPI_OPT_ECN 8
-
-
struct tcp_info {
-
__u8 tcpi_state;
-
__u8 tcpi_ca_state;
-
__u8 tcpi_retransmits;
-
__u8 tcpi_probes;
-
__u8 tcpi_backoff;
-
__u8 tcpi_options;
-
__u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
-
-
__u32 tcpi_rto;
-
__u32 tcpi_ato;
-
__u32 tcpi_snd_mss;
-
__u32 tcpi_rcv_mss;
-
-
__u32 tcpi_unacked;
-
__u32 tcpi_sacked;
-
__u32 tcpi_lost;
-
__u32 tcpi_retrans;
-
__u32 tcpi_fackets;
-
-
-
__u32 tcpi_last_data_sent;
-
__u32 tcpi_last_ack_sent;
-
__u32 tcpi_last_data_recv;
-
__u32 tcpi_last_ack_recv;
-
-
-
__u32 tcpi_pmtu;
-
__u32 tcpi_rcv_ssthresh;
-
__u32 tcpi_rtt;
-
__u32 tcpi_rttvar;
-
__u32 tcpi_snd_ssthresh;
-
__u32 tcpi_snd_cwnd;
-
__u32 tcpi_advmss;
-
__u32 tcpi_reordering;
-
-
__u32 tcpi_rcv_rtt;
-
__u32 tcpi_rcv_space;
-
-
__u32 tcpi_total_retrans;
-
};
函数实现
内核版本:2.6.37
-
int tcp_getsockopt (struct sock *sk, int level, int optname, char __user *optval, int __user *optlen)
-
{
-
struct inet_connection_sock *icsk = inet_csk(sk);
-
-
if (level != SOL_TCP)
-
return icsk->icsk_af_ops->getsockopt(sk, level, optname, optval, optlen);
-
-
return do_tcp_getsockopt(sk, level, optname, optval, optlen);
-
}
-
static int do_tcp_getsockopt (struct sock *sk, int level, int optname, char __user *optval, int __user *optlen)
-
{
-
struct inet_connection_sock *icsk = inet_csk(sk);
-
struct tcp_sock *tp = tcp_sk(sk);
-
int val, len;
-
-
if (get_user(len, optlen))
-
return -EFAULT;
-
-
len = min_t(unsigned int, len, sizeof(int));
-
if (len < 0)
-
return -EINVAL;
-
-
switch (optname) {
-
case TCP_MAXSEG:
-
val = tp->mss_cache;
-
if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE) | TCPF_LISTEN))
-
val = tp->rx_opt.user_mss;
-
break;
-
-
case TCP_NODELAY:
-
val = !! (tp->nonagle & TCP_NAGLE_OFF);
-
break;
-
-
case TCP_CORK:
-
val = !! (tp->nonagle & TCP_NAGLE_CORK);
-
break;
-
-
case TCP_KEEPIDLE:
-
val = keepalive_time_when(tp) / HZ;
-
break;
-
-
case TCP_KEEPINTVL:
-
val = keepalive_intvl_when(tp) / HZ;
-
break;
-
-
case TCP_KEEPCNT:
-
val = keepalive_probes(tp);
-
break;
-
-
case TCP_SYNCNT:
-
val = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
-
break;
-
-
case TCP_LINGER2:
-
val = tp->linger2;
-
if (val >= 0)
-
val = (val ? : sysctl_tcp_fin_timeout) / HZ;
-
-
case TCP_DEFER_ACCEPT:
-
...
-
-
case TCP_WINDOW_CLAMP:
-
val = tp->window_clamp;
-
break;
-
-
case TCP_INFO: {
-
struct tcp_info info;
-
-
if (get_user(len, optlen))
-
return -EFAULT;
-
-
tcp_get_info(sk, &info);
-
-
len = min_t(unsigned int, len, sizeof(info));
-
-
if (put_user(len, optlen))
-
return -EFAULT;
-
-
if (copy_to_user(optval, &info, len))
-
return -EFAULT;
-
-
return 0;
-
}
-
-
case TCP_QUICKACK:
-
val = ! icsk->icsk_ack.pingpong;
-
break;
-
-
case TCP_CONGESTION:
-
if (get_user(len, optlen))
-
return -EFAULT;
-
-
len = min_t(unsigned int, len, TCP_CA_NAME_MAX);
-
-
if (put_user(len, optlen)
-
return -EFAULT;
-
-
if (copy_to_user(optval, icsk->icsk_ca_ops->name, len))
-
return -EFAULT;
-
-
return 0;
-
-
case TCP_COOKIE_TRANSACTIONS :
-
...
-
-
case TCP_THIN_LINEAR_TIMEOUTS:
-
val = tp->thin_lto;
-
break;
-
-
case TCP_THIN_DUPACK:
-
val = tp->thin_dupack;
-
break;
-
-
case TCP_USER_TIMEOUT:
-
val = jiffies_to_msecs(icsk->icsk_user_timeout);
-
break;
-
-
default:
-
return -ENOPROTOOPT;
-
}
-
-
if (put_user(len, optlen))
-
return -EFAULT;
-
-
if (copy_to_user(optval, &val, len))
-
return -EFAULT;
-
-
return 0;
-
}
-
static inline int keepalive_time_when(const struct tcp_sock *tp)
-
{
-
return tp->keepalive_time ? : sysctl_tcp_keepalive_time;
-
}
-
-
static inline int keepalive_intvl_when(const struct tcp_sock *tp)
-
{
-
return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl;
-
}
-
-
static inline int keepalive_probes(const struct tcp_sock *tp)
-
{
-
return tp->keepalive_probes ? : sysctl_tcp_keepalive_probes;
-
}
TCP_INFO
-
-
-
void tcp_get_info(struct sock *sk, struct tcp_info *info)
-
{
-
struct tcp_sock *tp = tcp_sk(sk);
-
const struct inet_connection_sock *icsk = inet_csk(sk);
-
u32 now = tcp_time_stamp;
-
-
memset(info, 0, sizeof(*info));
-
-
info->tcpi_state = sk->sk_state;
-
info->tcpi_ca_state = icsk_ca_state;
-
info->tcpi_retransmits = icsk->icsk_retransmits;
-
info->tcpi_probes = icsk->icsk_probes_out;
-
info->tcpi_backoff = icsk->icsk_backoff;
-
-
if (tp->rx_opt.tstamp_ok)
-
info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
-
if (tcp_is_sack(tp))
-
info->tcpi_options |= TCPI_OPT_SACK;
-
if (tp->rx_opt.wscale_ok) {
-
info->tcpi_options |= TCPI_OPT_WSCALE;
-
info->tcpi_snd_wscale = tp->rx_opt.snd_wscale;
-
info->tcpi_rcv_wscale = tp->rx_opt.rcv_wscale;
-
}
-
-
if (tp->ecn_flags & TCP_ECN_OK)
-
info->tcpi_options |= TCPI_OPT_ECN;
-
-
info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto);
-
info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato);
-
info->tcpi_snd_mss = tp->mss_cache;
-
info->tcpi_rcv_mss = icsk->icsk_ack.rcv_mss;
-
-
if (sk->sk_state == TCP_LISTEN) {
-
info->tcpi_unacked = sk->sk_ack_backlog;
-
info->tcpi_sacked = sk->sk_max_ack_backlog;
-
-
} else {
-
info->tcpi_unacked = tp->packets_out;
-
info->tcpi_sacked = tp->sacked_out;
-
}
-
-
info->tcpi_lost = tp->lost_out;
-
info->tcpi_retrans = tp->retrans_out;
-
info->tcpi_fackets = tp->fackets_out;
-
-
info->tcpi_last_data_sent = jiffies_to_msecs(now - tp->lsndtime);
-
info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime);
-
info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp);
-
-
info->tcpi_pmtu = icsk->icsk_pmtu_cookie;
-
info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
-
info->tcpi_rtt = jiffies_to_usecs(tp->srtt) >> 3;
-
info->tcpi_rttvar = jiffies_to_usecs(tp->mdev) >> 2;
-
-
info->tcpi_snd_ssthresh = tp->snd_ssthresh;
-
info->tcpi_snd_cwnd = tp->snd_cwnd;
-
info->tcpi_advmss = tp->advmss;
-
info->tcpi_reordering = tp->reordering;
-
-
info->tcpi_rcv_rtt = jiffies_to_usecs(tp->rcv_rtt_est.rtt) >> 3;
-
info->tcpi_rcv_space = tp->rcvq_space.space;
-
-
info->tcpi_total_retrans = tp->total_retrans;
-
}
阅读(2325) | 评论(0) | 转发(0) |