0
点赞
收藏
分享

微信扫一扫

内核协议栈 netfilter中tproxy新版本对比

 由于:linux 新内核tcp/ip协议栈中添加了 TCP_NEW_SYN_RECV; 所以 在判断sk是否为transparent 时 需要考虑其状态;

static bool tproxy_sk_is_transparent(struct sock *sk)
{
switch (sk->sk_state) {
case TCP_TIME_WAIT:
if (inet_twsk(sk)->tw_transparent)
return true;
break;
case TCP_NEW_SYN_RECV:
if (inet_rsk(inet_reqsk(sk))->no_srccheck)
return true;
break;
default:
if (inet_sk(sk)->transparent)
return true;
}

sock_gen_put(sk);
return false;
}

 

/**
* tcp_make_synack - Prepare a SYN-ACK.
* sk: listener socket
* dst: dst entry attached to the SYNACK
* req: request_sock pointer
*
* Allocate one skb and build a SYNACK packet.
* @dst is consumed : Caller should not use it again.
*/
struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
struct request_sock *req,
struct tcp_fastopen_cookie *foc,
bool attach_req)
{
struct inet_request_sock *ireq = inet_rsk(req);
const struct tcp_sock *tp = tcp_sk(sk);
struct tcp_md5sig_key *md5 = NULL;
struct tcp_out_options opts;
struct sk_buff *skb;
int tcp_header_size;
struct tcphdr *th;
u16 user_mss;
int mss;

skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC);
-------------------------------
if (attach_req) {
skb_set_owner_w(skb, req_to_sk(req));
} else {
/* sk is a const pointer, because we want to express multiple
* cpu might call us concurrently.
* sk->sk_wmem_alloc in an atomic, we can promote to rw.
*/
skb_set_owner_w(skb, (struct sock *)sk);
}

-----------------------------------
}

 

处理syn包回复syn_ack时, 设置回复报文skb结构时, 其skb->sk 可能指向req_sock 可能指向listen sk;此时和以前内核版本不一样;

所以后续处理报文以及判断此skb的transparent属性时 需要判断其sk具体指向以及数值

 

对于 sk 的释放:

/* All sockets share common refcount, but have different destructors */
void sock_gen_put(struct sock *sk)
{
if (!atomic_dec_and_test(&sk->sk_refcnt))
return;

if (sk->sk_state == TCP_TIME_WAIT)
inet_twsk_free(inet_twsk(sk));
else if (sk->sk_state == TCP_NEW_SYN_RECV)
reqsk_free(inet_reqsk(sk));
else
sk_free(sk);
}
EXPORT_SYMBOL_GPL(sock_gen_put);

void sock_edemux(struct sk_buff *skb)
{
sock_gen_put(skb->sk);
}

/* assign a socket to the skb -- consumes sk */
static void
nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
{
  skb_orphan(skb);
  skb->sk = sk;
  skb->destructor = sock_edemux;
}

也就是需要分各种状态释放skb->sk

 

http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!! 但行好事 莫问前程 --身高体重180的胖子

举报

相关推荐

0 条评论