[완료]getpeername(0 에 의미는 무엇인가요

anaud2의 이미지

안녕하세요

질문을 드릴게 있습니다. 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번을 놓는 의미는 무엇일까요

bushi의 이미지

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를 사용하는 서버에서 0번 디스크립터는 접속된 클라이언트의 fd 값입니다.

inetd에서 0번 fd에 클라이언트 fd를 복사해서 넘겨줍니다.

결국, 클라이언트 소켓을 체크하는 루틴입니다.

------------------------------------------
http://onestep.tistory.com

Just do it!

anaud2의 이미지

네 저도 0번 디스크립터는 접속한 클라이언트의 fd라고 생각합니다.

그런데

if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
        syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
        exit(1);
}

리눅스(xinetd)에서는 접속한 클라이언트의 주소가 정확하게 넘어 오는데 선솔라리스에서는 주소값이 저장이안됩니다.

리눅스
his_addr.port[7457] 
his_addr.sin_addr.s_addr[-503207744]
his_addr.sin_famly[2]
 
유닉스
his_addr.port[8466]
his_addr.sin_addr.s_addr[0]
his_addr.sin_famly[26]

왜 저렇게 문제가 되는지 알지를 못해서 질문을 올렸었어요 inetd와 xinetd 모두 0번은 접속한 클라이언트 소켓의fd로 알고 있는데 왜 안될까요
제대로된 socket의 fd가 넘어올경우 getpeername함수의 경우 주소를 올바르게 저장이 되더라구요(선솔라리스에서 간단한 소켓프로그램을 만들어서 확인해봤습니다.)
왜 저렇게 되는지 도통 헷갈리네요

태훈의 이미지

주소체계값이 AF_INET6 으로 넘어오는 것부터 잘못된 정보가 넘어오는 군요.

저의 짧은 소견으로는 inetd나 ftp 서버에 별다른 문제가 없다면 엔디안 문제가 아닐까 생각합니다.

------------------------------------------
http://onestep.tistory.com

Just do it!

bushi의 이미지

뭐가 헷갈린다는 건지 도통 모르겠습니다.
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]$ 

[bushi@rose inetd_ipv6]$ ssh -4 localhost -p 80
ssh_exchange_identification: Connection closed by remote host
[bushi@rose inetd_ipv6]$ 
[bushi@rose inetd_ipv6]$ cat /tmp/log
Client IPv4 address is 127.0.0.1
Client port is 35973
[bushi@rose inetd_ipv6]$ 
[bushi@rose inetd_ipv6]$ 
[bushi@rose inetd_ipv6]$ ssh -6 localhost -p 80
ssh_exchange_identification: Connection closed by remote host
[bushi@rose inetd_ipv6]$ 
[bushi@rose inetd_ipv6]$ 
[bushi@rose inetd_ipv6]$ cat /tmp/log
Client IPv6 address is ::1
Client port is 44748
[bushi@rose inetd_ipv6]$ 

OS 가 IPv4 를 기준으로 잡는지 IPv6 를 기준으로 잡는지 (이거 말이 참 애매하네요. 이쪽을 정확히 알지를 못하니...) 까지 알아야만 구현이 가능한 분야는 아닌 것 같은데요.

OTL

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.