|
发表于 2023-5-16 11:02:31
|
显示全部楼层
不需要开65535个“应用”,一个进程就够用了,想知道具体会发生什么可以直接自己试试,这是 Linux 上能运行的代码,编译要链接 libcap(-lcap),需要 root 运行或者给 CAP_NET_BIND_SERVICE
- #include <arpa/inet.h>
- #include <errno.h>
- #include <netinet/in.h>
- #include <signal.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/capability.h>
- #include <sys/socket.h>
- #include <unistd.h>
- static bool check_capability() {
- cap_t capabilities = cap_get_proc();
- bool result = false;
- do {
- if (capabilities == NULL) {
- perror("cap_get_proc");
- exit(EXIT_FAILURE);
- }
- cap_flag_value_t value;
- if (cap_get_flag(capabilities, CAP_NET_BIND_SERVICE, CAP_EFFECTIVE, &value) == -1) {
- perror("cap_get_flag");
- exit(EXIT_FAILURE);
- }
- if (value == CAP_SET) {
- result = true;
- break;
- }
- if (cap_get_flag(capabilities, CAP_NET_BIND_SERVICE, CAP_PERMITTED, &value) == -1) {
- perror("cap_get_flag");
- exit(EXIT_FAILURE);
- }
- if (value == CAP_CLEAR) {
- result = false;
- break;
- }
- cap_value_t caps[] = {CAP_NET_BIND_SERVICE};
- if (cap_set_flag(capabilities, CAP_EFFECTIVE, 1, caps, CAP_SET) == -1) {
- perror("cap_set_flag");
- exit(EXIT_FAILURE);
- }
- if (cap_set_proc(capabilities) == -1) {
- perror("cap_set_proc");
- exit(EXIT_FAILURE);
- }
- result = true;
- } while (false);
- cap_free(capabilities);
- return result;
- }
- static void deal_with_permission() {
- if (geteuid() == 0) {
- return;
- }
- if (check_capability() == false) {
- }
- if (check_capability() == false) {
- fprintf(stderr, "permission denied.\n");
- exit(EXIT_FAILURE);
- }
- }
- static void handler(int sig) { return; }
- int main() {
- deal_with_permission();
- int fds[UINT16_MAX + 1];
- memset(fds, -1, sizeof(fds));
- struct sockaddr_in address = {.sin_family = AF_INET, .sin_port = 0, .sin_addr = {inet_addr("127.0.0.1")}};
- for (uint16_t i = 1; i != 0; i++) {
- address.sin_port = htons(i);
- fds[i] = socket(AF_INET, SOCK_STREAM, 0);
- int ret = bind(fds[i], (struct sockaddr *)&address, sizeof(address));
- if (ret == 0) {
- printf("bind (fd)%d -> (port)%d\n", fds[i], i);
- } else {
- printf("failed to bind to (port)%d: %s\n", i, strerror(errno));
- close(fds[i]);
- fds[i] = -1;
- }
- }
- signal(SIGINT, handler);
- printf("signal me (pid=%d) with SIGINT to cleanup, waiting...\n", getpid());
- pause();
- for (uint16_t i = 1; i != 0; i++) {
- if (fds[i] != -1) {
- close(fds[i]);
- }
- }
- return 0;
- }
复制代码 |
|