From 48ae4ebb805c66edd8b9c5871e833df30dd9814c Mon Sep 17 00:00:00 2001 From: yangxin <245051644@qq.com> Date: Wed, 1 Mar 2023 02:20:18 +0000 Subject: [PATCH] Add remote port query. Signed-off-by: yangxin <245051644@qq.com> --- qtfs/comm.h | 2 ++ qtfs/misc.c | 13 +++++++++++ qtfs/qtfs/syscall.c | 27 +++++++++++++++++++++++ qtfs/qtfs_server/fsops.c | 47 ++++++++++++++++++++++++++++++++++++++++ qtfs/req.h | 20 +++++++++++++++++ 5 files changed, 109 insertions(+) diff --git a/qtfs/comm.h b/qtfs/comm.h index 84a6b09..2a7ef3d 100644 --- a/qtfs/comm.h +++ b/qtfs/comm.h @@ -28,6 +28,7 @@ enum { _QTFS_IOCTL_LOG_LEVEL, _QTFS_IOCTL_EPOLL_SUPPORT, _QTFS_IOCTL_UDS_PROXY_PID, + _QTFS_IOCTL_QUERY_PORT, }; #define QTFS_IOCTL_THREAD_INIT _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_EXEC) @@ -42,6 +43,7 @@ enum { #define QTFS_IOCTL_LOGLEVEL _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_LOG_LEVEL) #define QTFS_IOCTL_EPOLL_SUPPORT _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_EPOLL_SUPPORT) #define QTFS_IOCTL_UDS_PROXY_PID _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_UDS_PROXY_PID) +#define QTFS_IOCTL_QUERYPORT _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_QUERY_PORT) #define QTINFO_MAX_EVENT_TYPE 36 // look qtreq_type at req.h #define QTFS_FUNCTION_LEN 64 diff --git a/qtfs/misc.c b/qtfs/misc.c index 44da4e1..6e31390 100644 --- a/qtfs/misc.c +++ b/qtfs/misc.c @@ -53,6 +53,10 @@ void qtfs_misc_flush_threadstate(void) qtfs_diag_info->epoll_state = (qtfs_epoll_var == NULL) ? -1 : qtfs_epoll_var->state; } +#ifdef QTFS_CLIENT +extern int qtfs_query_port(void *query_req); +#endif + void qtfs_req_size(void) { qtfs_diag_info->req_size[QTFS_REQ_NULL] = sizeof(struct qtreq); @@ -84,6 +88,7 @@ void qtfs_req_size(void) qtfs_diag_info->req_size[QTFS_REQ_FIFOPOLL] = sizeof(struct qtreq_poll); qtfs_diag_info->req_size[QTFS_REQ_EPOLL_CTL] = sizeof(struct qtreq_epollctl); qtfs_diag_info->req_size[QTFS_REQ_EPOLL_EVENT] = sizeof(struct qtreq_epollevt); + qtfs_diag_info->req_size[QTFS_REQ_QUERYPORT] = sizeof(struct qtreq_queryport); qtfs_diag_info->rsp_size[QTFS_REQ_NULL] = sizeof(struct qtreq); qtfs_diag_info->rsp_size[QTFS_REQ_IOCTL] = sizeof(struct qtrsp_ioctl); @@ -114,6 +119,7 @@ void qtfs_req_size(void) qtfs_diag_info->rsp_size[QTFS_REQ_FIFOPOLL] = sizeof(struct qtrsp_poll); qtfs_diag_info->rsp_size[QTFS_REQ_EPOLL_CTL] = sizeof(struct qtrsp_epollctl); qtfs_diag_info->rsp_size[QTFS_REQ_EPOLL_EVENT] = sizeof(struct qtrsp_epollevt); + qtfs_diag_info->rsp_size[QTFS_REQ_QUERYPORT] = sizeof(struct qtrsp_queryport); } long qtfs_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -147,6 +153,13 @@ long qtfs_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ret = (long)qtfs_log_init(level_str); break; } +#ifdef QTFS_CLIENT + case QTFS_IOCTL_QUERYPORT: + { + ret = qtfs_query_port((void *)arg); + break; + } +#endif case QTFS_IOCTL_EPOLL_SUPPORT: { if (arg == 0) { diff --git a/qtfs/qtfs/syscall.c b/qtfs/qtfs/syscall.c index 8133a06..2560cd0 100644 --- a/qtfs/qtfs/syscall.c +++ b/qtfs/qtfs/syscall.c @@ -544,3 +544,30 @@ int qtfs_syscall_fini(void) #endif return 0; } + +int qtfs_query_port(void *query_req) +{ + struct qtfs_sock_var_s *pvar = qtfs_conn_get_param(); + struct qtreq_queryport *req; + struct qtrsp_queryport *rsp; + int optslen; + copy_from_user(&optslen, query_req, sizeof(int)); + int ret; + + if (!pvar) { + qtfs_err("Failed to get qtfs sock var"); + return -EINVAL; + } + + req = qtfs_sock_msg_buf(pvar, QTFS_SEND); + rsp = qtfs_sock_msg_buf(pvar, QTFS_RECV); + copy_from_user(req, query_req, sizeof(struct qtreq_queryport) + optslen * sizeof(struct socketopt)); + rsp = qtfs_remote_run(pvar, QTFS_REQ_QUERYPORT, sizeof(struct qtreq_queryport) + optslen * sizeof(struct socketopt)); + if (IS_ERR(rsp) || rsp == NULL) { + qtfs_conn_put_param(pvar); + return -EINVAL; + } + ret = rsp->ret; + qtfs_conn_put_param(pvar); + return ret; +} diff --git a/qtfs/qtfs_server/fsops.c b/qtfs/qtfs_server/fsops.c index bf16d14..4e8e1c2 100644 --- a/qtfs/qtfs_server/fsops.c +++ b/qtfs/qtfs_server/fsops.c @@ -1178,6 +1178,51 @@ end: return sizeof(struct qtrsp_llseek); } +int handle_query_port(struct qtserver_arg *arg) +{ + struct qtreq_queryport *req = (struct qtreq_queryport *)REQ(arg); + struct qtrsp_queryport *rsp = (struct qtrsp_queryport *)RSP(arg); + struct sockaddr *saddr; + struct socket *sock; + int ret, err, i; + size_t addrlen; + struct sockaddr_in *addr4; + char ip_str[17]; + addr4 = (struct sockaddr_in *)&(req->addr); + saddr = &(req->addr); + switch (saddr->sa_family) { + case AF_INET6: + addrlen = sizeof(struct sockaddr_in6); + break; + case AF_INET: + addrlen = sizeof(struct sockaddr_in); + break; + default: + rsp->ret = -EAFNOSUPPORT; + return sizeof(struct qtrsp_queryport); + } + ret = sock_create_kern(&init_net, saddr->sa_family, SOCK_STREAM, 0, &sock); + if (ret) { + qtfs_err("handle_query_port create sock failed.\n"); + rsp->ret = ret; + } else { + for (i = 0; i < req->optslen; i++) { + sockptr_t optval = KERNEL_SOCKPTR(req->opts[i].optval); + if (req->opts[i].level == SOL_SOCKET) + err = sock_setsockopt(sock, req->opts[i].level, req->opts[i].optname, optval, req->opts[i].optlen); + else if (unlikely(!sock->ops->setsockopt)) + err = -EOPNOTSUPP; + else + err = sock->ops->setsockopt(sock, req->opts[i].level, req->opts[i].optname, optval, req->opts[i].optlen); + } + ret = sock->ops->bind(sock, saddr, addrlen); + rsp->ret = ret; + } + sock_release(sock); + + return sizeof(struct qtrsp_queryport); +} + int handle_exit(struct qtserver_arg *arg) { return 4; @@ -1228,6 +1273,8 @@ static struct qtserver_ops qtfs_server_handles[] = { {QTFS_REQ_LLSEEK, handle_llseek, "llseek"}, + {QTFS_REQ_QUERYPORT, handle_query_port, "query_port"}, + {QTFS_REQ_EXIT, handle_exit, "exit"}, // keep this handle at the end }; diff --git a/qtfs/req.h b/qtfs/req.h index 29f8964..1aeb757 100644 --- a/qtfs/req.h +++ b/qtfs/req.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "log.h" enum qtreq_type { @@ -46,6 +47,7 @@ enum qtreq_type { QTFS_REQ_LLSEEK, + QTFS_REQ_QUERYPORT, QTFS_REQ_EXIT, // exit server thread QTFS_REQ_INV, }; @@ -508,6 +510,24 @@ struct qtrsp_epollctl { int ret; }; +#define LEN 264 +struct socketopt +{ + int level; + int optname; + char optval[LEN]; + unsigned int optlen; +}; + +struct qtreq_queryport { + int optslen; + struct sockaddr addr; + struct socketopt opts[0]; +}; + +struct qtrsp_queryport { + int ret; +}; // server epoll 通知 client #define QTFS_EPOLL_MAX_EVENTS 128 -- Gitee