-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathpriv_command.c
executable file
·77 lines (68 loc) · 2.15 KB
/
priv_command.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "priv_command.h"
#include "common.h"
#include "sysutil.h"
#include "priv_sock.h"
#include "configure.h"
//获取数据套接字
void privop_pasv_get_data_sock(Session_t *sess)
{
char ip[16] = {0};
priv_sock_recv_str(sess->nobody_fd, ip, sizeof ip);
uint16_t port = priv_sock_recv_int(sess->nobody_fd);
//创建fd
int data_fd = tcp_client(20);
struct sockaddr_in addr;
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons(port);
int ret = connect_timeout(data_fd, &addr, tunable_connect_timeout);
if(ret == -1)
ERR_EXIT("connect_timeout");
priv_sock_send_result(sess->nobody_fd, PRIV_SOCK_RESULT_OK);
priv_sock_send_fd(sess->nobody_fd, data_fd);
close(data_fd);
}
//判断pasv模式是否开启
void privop_pasv_active(Session_t *sess)
{
//发给proto结果
priv_sock_send_int(sess->nobody_fd, (sess->listen_fd != -1));
}
//获取监听fd
void privop_pasv_listen(Session_t *sess)
{
//创建listen fd
char ip[16] = {0};
get_local_ip(ip);
int listenfd = tcp_server(ip, 20);
sess->listen_fd = listenfd;
struct sockaddr_in addr;
socklen_t len = sizeof addr;
if(getsockname(listenfd, (struct sockaddr*)&addr, &len) == -1)
ERR_EXIT("getsockname");
//发送应答
priv_sock_send_result(sess->nobody_fd, PRIV_SOCK_RESULT_OK);
//发送port
uint16_t net_endian_port = ntohs(addr.sin_port);
priv_sock_send_int(sess->nobody_fd, net_endian_port);
}
//accept一个新的连接
void privop_pasv_accept(Session_t *sess)
{
//接受新连接
int peerfd = accept_timeout(sess->listen_fd, NULL, tunable_accept_timeout);
//清除状态
close(sess->listen_fd);
sess->listen_fd = -1;
if(peerfd == -1)
{
priv_sock_send_result(sess->nobody_fd, PRIV_SOCK_RESULT_BAD);
ERR_EXIT("accept_timeout");
}
//给对方回应
priv_sock_send_result(sess->nobody_fd, PRIV_SOCK_RESULT_OK);
//将data fd传给对方
priv_sock_send_fd(sess->nobody_fd, peerfd);
close(peerfd);
}