[완료]getpeername(0 에 의미는 무엇인가요
글쓴이: anaud2 / 작성시간: 수, 2009/01/14 - 3:17오후
안녕하세요
질문을 드릴게 있습니다. getpeername은 특정 파일 디스크립트에 접속한 사용자 정보(?)를 알아내는 함수인데요
if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
exit(1);
}위의 소스처럼 파일 디스크립트를 0으로 넣어줬습니다. 이유는 무엇인가요?
0은 stdin인데요 표준 입력을 사용하는 녀석의 정보를 나타내게 하는것일까요?
위의 소스는 ftp데몬의 한부분인데요 질문을 드리는 이유는 리눅스에서는 안그런데 선솔라리스5.9에서만 his_addr.sin_addr.s_addr값 즉 주소값이 저장이 안됩니다.
함수가 실패도 아닌데 말이죠 포트와 주소체계값은 AF_INET6으로 들어옵니다.(리눅스로 돌릴땐 같은 클라이언트가 AF_INET이었는데 체계도 틀리게 나옵니다.)
ftp 데몬은 inetd 방식으로 구동이 되고 있습니다.
저기에 구조체에 주소값이 들어갈수 있게 하기 위해 방법을 찾고 있습니다.
간단한 TCP/IP프로그램에서는 getpeername함수를 호출하면서 클라이언트의 소켓넘버를 인자로 주면 정확하게 구조체에 클라이언트의 정보가 저장이 되었는데요
ftp데몬이라 0번을 하는 무슨 의미가 있을것 같은데 또 main문 최초 시작에 호출이 되고 있어서 접속한 클라이언트의 소켓 넘버도 없는데 어떻게 해야할지 막막합니다.
파일디스크립트를 0번을 놓는 의미는 무엇일까요
Forums:


inetd(혹은 xinetd) 에
inetd(혹은 xinetd) 에 의해 실행된 서버 프로세스의 0번 디스크립터의 정체.
에 대해 리눅스와 sunos 에서 조사를 해보시면 될 것 같지 않습니까 ?
간단한 예를 들면, bash 로 만든 웹서버
[bushi@rose xinetd.d]$ cat /etc/xinetd.d/httpd_bash service http { disable = no socket_type = stream protocol = tcp wait = no user = nobody server = /usr/sbin/httpd.sh } [bushi@rose xinetd.d]$ [bushi@rose xinetd.d]$ cat /usr/sbin/httpd.sh #!/bin/sh echo -en "HTTP/1.0 200 OK\r\n" echo -en "Content-Type: text/html\r\n\r\n" echo "<h1>bye~ bye~</h1>" [bushi@rose xinetd.d]$OTL
inetd를 사용하는
inetd를 사용하는 서버에서 0번 디스크립터는 접속된 클라이언트의 fd 값입니다.
inetd에서 0번 fd에 클라이언트 fd를 복사해서 넘겨줍니다.
결국, 클라이언트 소켓을 체크하는 루틴입니다.
------------------------------------------
http://onestep.tistory.com
Just do it!
네 저도 0번
네 저도 0번 디스크립터는 접속한 클라이언트의 fd라고 생각합니다.
그런데
if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) { syslog(LOG_ERR, "getpeername (%s): %m",argv[0]); exit(1); }리눅스(xinetd)에서는 접속한 클라이언트의 주소가 정확하게 넘어 오는데 선솔라리스에서는 주소값이 저장이안됩니다.
왜 저렇게 문제가 되는지 알지를 못해서 질문을 올렸었어요 inetd와 xinetd 모두 0번은 접속한 클라이언트 소켓의fd로 알고 있는데 왜 안될까요
제대로된 socket의 fd가 넘어올경우 getpeername함수의 경우 주소를 올바르게 저장이 되더라구요(선솔라리스에서 간단한 소켓프로그램을 만들어서 확인해봤습니다.)
왜 저렇게 되는지 도통 헷갈리네요
주소체계값이 AF_INET6
주소체계값이 AF_INET6 으로 넘어오는 것부터 잘못된 정보가 넘어오는 군요.
저의 짧은 소견으로는 inetd나 ftp 서버에 별다른 문제가 없다면 엔디안 문제가 아닐까 생각합니다.
------------------------------------------
http://onestep.tistory.com
Just do it!
뭐가 헷갈린다는
뭐가 헷갈린다는 건지 도통 모르겠습니다.
AF_INET6 로 넘어온다면 그에 맞게 처리를 해주면 그 뿐 아닙니까 ?
[bushi@rose inetd_ipv6]$ cat test.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main(int argc, char **argv) { struct sockaddr_in6 clientaddr6; struct sockaddr_in clientaddr4; socklen_t addrlen6 = sizeof(clientaddr6); socklen_t addrlen4 = sizeof(clientaddr4); char str[128]; int ret; FILE *fp = fopen("/tmp/log", "w+"); if (!fp) return EXIT_FAILURE; ret = getpeername(0, (struct sockaddr *)&clientaddr4, &addrlen4); if (ret < 0) { fprintf(fp, "getpeername(ipv4): %s\n", strerror(errno)); goto out; } if (clientaddr4.sin_family == AF_INET6) { goto _ipv6; } if(inet_ntop(AF_INET, &clientaddr4.sin_addr, str, sizeof(str))) { fprintf(fp, "Client IPv4 address is %s\n", str); fprintf(fp, "Client port is %d\n", ntohs(clientaddr4.sin_port)); } goto out; _ipv6: ret = getpeername(0, (struct sockaddr *)&clientaddr6, &addrlen6); if (ret < 0) { fprintf(fp, "getpeername(ipv6): %s\n", strerror(errno)); goto out; } if(inet_ntop(AF_INET6, &clientaddr6.sin6_addr, str, sizeof(str))) { fprintf(fp, "Client IPv6 address is %s\n", str); fprintf(fp, "Client port is %d\n", ntohs(clientaddr6.sin6_port)); } goto out; out: fclose(fp); return EXIT_SUCCESS; } [bushi@rose inetd_ipv6]$ [bushi@rose inetd_ipv6]$ !gcc gcc -o test test.c -Wall [bushi@rose inetd_ipv6]$[bushi@rose inetd_ipv6]$ cat /etc/xinetd.d/test service http { disable = no socket_type = stream protocol = tcp flags = IPv6 wait = no user = root server = /home/bushi/net/inetd_ipv6/test } [bushi@rose inetd_ipv6]$ [bushi@rose inetd_ipv6]$ sudo service xinetd restart Stopping xinetd: [FAILED] Starting xinetd: [ OK ] [bushi@rose inetd_ipv6]$OS 가 IPv4 를 기준으로 잡는지 IPv6 를 기준으로 잡는지 (이거 말이 참 애매하네요. 이쪽을 정확히 알지를 못하니...) 까지 알아야만 구현이 가능한 분야는 아닌 것 같은데요.
OTL
댓글 달기