• 不同linux操作系统的内存管理及安全性


    不同linux操作系统的内存管理及安全性

    20191331 lyx

    1.前言

    今天编程时遇到一个非常有趣的现象————编写了一个socket网络通信程序,使用一台虚拟机(openeuler 20.03 LTS)做客户端,另外一台云服务器(Ubuntu 18.04 server 64bit with ARM)和一台虚拟机(kali linux4.19.0-kali4-amd64 )做服务端。程序非常简单,即客户端和服务端建立socket连接,服务端返回当前时间。但却出现了两种实验结果。

    环境:

    代码如下:

    ********************client.c*************************
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <errno.h>
    #include <net/if.h>
    #include <sys/ioctl.h>
    
    #define RIO_BUFSIZE 8192
    
    typedef struct sockaddr SA;
    typedef struct{
        int rio_fd;
        int rio_cnt;
        char *rio_bufptr;
        char rio_buf[RIO_BUFSIZE];
    
    }rio_t;
    
    #define MAXLINE 200
    
    int get_local_ip(const char *eth_inf,char *ipBuf)
    {
        int sd;
        struct sockaddr_in sin;
        struct ifreq ifr;
     
        sd = socket(AF_INET, SOCK_DGRAM, 0);
        if (-1 == sd)
        {
            printf("socket error: %s\n", strerror(errno));
            return -1;
        }
     
        strncpy(ifr.ifr_name, eth_inf, IFNAMSIZ);
        ifr.ifr_name[IFNAMSIZ - 1] = 0;
     
        // if error: No such device  
        if (ioctl(sd, SIOCGIFADDR, &ifr) < 0)
        {
            printf("ioctl error: %s\n", strerror(errno));
            close(sd);
            return -1;
        }
        
        snprintf(ipBuf ,50,"%s" ,inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr)); 
    
        close(sd);
        return 0;
    }
    
    
    int open_clientfd(char *hostname,int port){
    
        int clientfd;
        struct hostent *hp;
        struct sockaddr_in serveraddr;
    
        if((clientfd = socket(AF_INET,SOCK_STREAM,0))<0)
            return -1;
    
        if((hp = gethostbyname(hostname))==NULL)
            return -2;
    
        bzero((char *)&serveraddr,sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        bcopy((char *)hp->h_addr_list[0],
                (char *)&serveraddr.sin_addr.s_addr,hp->h_length);
        serveraddr.sin_port = htons(port);
    
        if(connect(clientfd,(SA *)&serveraddr,sizeof(serveraddr))<0)
            return -1;
        
        return clientfd;
    }
    
    
    
    int main(int argc,char **argv){
    
        int clientfd,port;
        char *host,buf[MAXLINE];
        char myhost[32] = "";
        char sbuf[MAXLINE];
        char rbuf[MAXLINE];
        rio_t rio;
        char str1[MAXLINE]="Client IP:";
        char str2[MAXLINE]="Server Implementer:20191331";
        
        char str3[MAXLINE]="Current Time:";
    
        if(argc!=3){
        
            fprintf(stderr,"usage:%s <host> <port>\n",argv[0]);
            exit(0);
        }
        get_local_ip("enp0s3",myhost);
        host = argv[1];
        port = atoi(argv[2]);
    
        clientfd = open_clientfd(host,port);
      
        while(1){
            
    
            recv(clientfd,rbuf,MAXLINE,0);
    
            printf("%s",str1);
            puts(myhost);
    
            printf("%s",str2);
            putchar('\n');
    
            printf("%s",str3);
          
            puts(rbuf);
           
            close(clientfd);
           
            exit(0);
        }
    
    }
    
    
    *************************server.c************************
    #include <stdio.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>    
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include <math.h>
    #include <errno.h>
    #include <net/if.h>
    #include <sys/ioctl.h>
    
    #define MAXLINE 200
    #define RIO_BUFSIZE 8192
    #define LISTENQ 1024
    
    typedef struct{
        int rio_fd;
        int rio_cnt;
        char *rio_bufptr;
        char rio_buf[RIO_BUFSIZE];
    
    }rio_t;
    typedef struct sockaddr SA;
    
    typedef struct{
    int tm_sec;
    int tm_min;
    int tm_hour;
    int tm_mday;
    int tm_mon;
    int tm_year;
    int tm_wday;
    int tm_yday;
    int tm_isdst;
    }tm;
    
    int open_listenfd(int port){
    
        int listenfd,optval=1;
        struct sockaddr_in serveraddr;
    
        if((listenfd = socket(AF_INET,SOCK_STREAM,0))<0)
            return -1;
    
        if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,
                    (const void*)&optval,sizeof(int))<0)
            return -1;
    
        bzero((char *)&serveraddr,sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
        serveraddr.sin_port = htons((unsigned short)port);
        if(bind(listenfd,(SA*)&serveraddr,sizeof(serveraddr))<0)
            return -1;
    
        if(listen(listenfd,LISTENQ)<0)
            return -1;
    
        return listenfd;
    }
    
    
    void sigchld_handler(int sig){
    
        pid_t pid;
        int stat;
    
        while((pid = waitpid(-1,&stat,WNOHANG))>0){
            printf("child %d terminated\n",pid);
        }
        return;
    }
    
    int get_local_ip(const char *eth_inf,char *ipBuf)
    {
        int sd;
        struct sockaddr_in sin;
        struct ifreq ifr;
     
        sd = socket(AF_INET, SOCK_DGRAM, 0);
        if (-1 == sd)
        {
            printf("socket error: %s\n", strerror(errno));
            return -1;
        }
     
        strncpy(ifr.ifr_name, eth_inf, IFNAMSIZ);
        ifr.ifr_name[IFNAMSIZ - 1] = 0;
     
        // if error: No such device  
        if (ioctl(sd, SIOCGIFADDR, &ifr) < 0)
        {
            printf("ioctl error: %s\n", strerror(errno));
            close(sd);
            return -1;
        }
        
        snprintf(ipBuf ,50,"%s" ,inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr)); 
    
        close(sd);
        return 0;
    }
    
    
    int main(int argc,char **argv){
    
        int listenfd,connfd,port,clientlen;
        struct sockaddr_in clientaddr;
        struct hostent *hp;
        char *haddrp;
        char sbuf[MAXLINE];
        char rbuf[MAXLINE];
        char myhost[32] = "";
        rio_t rio;
        time_t lt;
        tm *local;
        char str1[MAXLINE]="Server IP:";
        char str2[MAXLINE]="Server Implementer:";
        char str3[MAXLINE]="Current Time:";
         
        
    
        if(argc != 2){
        
            fprintf(stderr,"usage:%s <port>\n",argv[0]);
            exit(0);
        }
    
        port = atoi(argv[1]);
    
        signal(SIGCHLD,sigchld_handler);
        listenfd = open_listenfd(port);
        while(1){
        
            clientlen = sizeof(clientaddr);
            connfd = accept(listenfd,(SA *)&clientaddr,&clientlen);
    
            hp = gethostbyaddr((const char*)&clientaddr.sin_addr.s_addr,
                    sizeof(clientaddr.sin_addr.s_addr),AF_INET);
            haddrp = inet_ntoa(clientaddr.sin_addr);
            printf("server connected to %s (%s)\n",hp->h_name,haddrp);
    
            if(fork() == 0){
            close(listenfd);
            lt = time(NULL); 
            local = localtime(&lt);
            strftime(sbuf,64,"%Y-%m-%d %H:%M:%S",local);
    	get_local_ip("enp0s3",myhost);
    	//send(connfd,myhost,MAXLINE,0);
    	strcat(sbuf,"\n");
    	strcat(sbuf,str1);
    	strcat(sbuf,myhost);
            send(connfd,sbuf,MAXLINE,0);
            close(connfd);
            exit(0);
            }
    
            close(connfd);
        }
    }
    
    

    然后运行时就发生了非常神奇的事

    在组(openeuler - kali)程序执行成功

    在组(openeuler - ubuntu)程序执行失败

    由此可见 不同操作系统对于内存管理的策略有所不同,安全性也有所不同。

    类Unix操作系统对比

    • centos作为服务器部署是第一选择。CentOS去除很多与服务器功能无关的应用,系统简单但非常稳定,命令行操作可以方便管理系统和应用,丰富的帮助文档和社区的支持。

    • ubuntu最佳的应用领域是桌面操作系统而非服务器操作系统。

    • Debian作为服务器的选择,但是由于其发展路线,使它的帮助文档相对于CentOS略少,技术资料也少。

    三大linux系统 内存安全 比较

    暂时没有找到linux内存安全的相关资料 D:

    但根据我以上实践的结果推测,可能是系统内核版本的原因,linux操作系统同出一源,区别不大,真正造成该现象的原因应该是内存管理策略的细微不同,也可能跟当时的系统状态有关。

  • 相关阅读:
    前端大文件分片上传/多线程上传
    网页大文件分片上传/多线程上传
    docker基础入门之二
    linux之iptable
    linux内核之网络协议栈
    ubuntu之iptables
    c++栈管理库TCMalloc、jeMalloc
    curl之post提交xml
    ceph基本操作整理
    docker基础入门之一
  • 原文地址:https://www.cnblogs.com/DKYcaiji/p/15590849.html
Copyright © 2020-2023  润新知