webserv 허용함수

개발새발·2022년 11월 18일
0

42Cursus

목록 보기
27/29
post-thumbnail

webserv

본 프로젝트의 개요와 프로젝트를 진행하기 위한 개념 확립

webserv 허용 함수

1. htons, htonl, ntohs, htohl

메모리에 값을 저장하는 방식에는 빅 엔디안(큰 단위부터 적는 방식)과 리틀 엔디안(작은 단위부터 적는 방식)이 있다. 보통 네트워크 통신에서는 헤더파일 확인이 가장 쉬운 빅 엔디안 방식을 사용하고 일반 PC에서는 연산이 빠른 리틀 엔디안 방식을 사용한다.

각각의 장단점으로 인해 방식이 둘로 나뉘게 되는데 이로인해 네트워크 통신을 할 때 문제가 발생한다. 전송하는 측은 빅 엔디안으로 전송을 하는데 받는 컴퓨터 입장에서는 리틀 엔디안으로 처리를 하기 때문에 실제로 데이터를 수신하면 원래 데이터와 달라져 버리는 것이다. 이 문제를 해결하기 위해 받는 측(리틀 엔디안)에서는 전송받은 데이터(빅 엔디안)를 뒤집어서 처리를 해주어야 한다.

리틀 엔디안을 빅 엔디안으로 변경하기 위해서는 htons(host to network short) 또는 htonl(host to network long)을 사용하면 된다. 포트는 2byte(16bit)로 이루어져있고 IP는 4byte(32bit)로 이루어져 있기 때문에, 포트번호를 처리하는 경우는 htons, IP주소를 처리하는 경우는 htonl을 사용한다.

반대로 빅 엔디안에서 리틀 엔디안으로의 변형은 ntohs(network to host short) 또는 ntohl(network to host long)을 사용한다.

  • 헤더 : #include <arpa/inet.h>
  • 형식
    • uint16_t htons(uint16_t hostshort)
    • uint32_t htonl(uint32_t hostlong)
    • uint16_t ntohs(uint16_t netshort)
    • uint32_t ntohl(uint32_t netlong)
  • 인자 : 빅 엔디안 혹은 리틀 엔디안으로 변환하고자 하는 값
  • 반환 : 변환된 값

2. inet_addr

인자로 들어간 string 타입의 데이터를 빅 엔디안 형식의 정수값으로 반환해 IP주소를 저장하는 sockaddr_in 구조체의 sin_addr에 저장

  • 헤더 : #include <arpa/inet.h>
  • 형식 : in_addr_t inet_addr(const char* string)
  • 인자 : 빅 엔디안으로 변환하고자 하는 값
  • 반환 :
    • 성공 시, string인자를 빅 엔디안 형식(32bit 정수값)으로 반환
    • 실패 시, INADDR_NONE 반환

3. socket

소켓 생성

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : int socket(int domain, int type, int protocol)
  • 인자 :
    • int domain : 어떤 네트워크(protocol family / address family)에서 사용할 것인지 지정
    • int type : 어떤 타입의 소켓을 생성할 것인지 지정
    • int protocol : 소켓에서 사용할 프로토콜 지정
  • 반환 :
    • 성공 시, 생성된 소켓의 디스크립터(0이상의 값) 반환
    • 실패 시, -1 반환
domain내용
PF_INET, AF_INETIPv4 프로토콜
PF_INET6, AF_INET6IPv6 프로토콜
PF_LOCAL, AF_UNIX같은 시스템 내에서 프로세스끼리 통신
PF_PACKETLow level socket을 위한 인터페이스
PF_IPXIPX 노벨 프로토콜을 사용

 

type내용
SOCK_STREAMTCP/IP 프로토콜
SOCK_DGRAMUDP/IP 프로토콜
SOCK_RAWRAW 방식(TCP나 UDP 사용하지 않고 바로 IP계층 사용)

 

protocol내용
IPPROTO_TCPTCP/IP 프로토콜
IPPROTO_UDPUDP/IP 프로토콜
0 (IPPROTO_HOPOPTS)첫 번째, 두 번째 매개변수를 기준으로 자동지정

4. setsockopt

소켓의 옵션 설정

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len)
  • 인자 :
    • int socket : 옵션을 변경할 소켓의 디스크립터
    • int level : 변경할 옵션의 프로토콜 레벨
    • int option_name : 변경할 옵션의 이름
    • const void *option_value : 변경 결과를 저장할 버퍼의 주소 값
    • socklen_t option_len : option_value로 전달된 옵션정보의 바이트 단위 크기
  • 반환 :
    • 성공 시, 0 반환
    • 실패 시, -1 반환

5. getsockname

소켓의 옵션 확인

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : int getsockopt(int socket, int level, int option_name, void *restrict option_value, socklen_t *restrict option_len)
  • 인자 :
    • int socket : 옵션을 확인할 소켓의 디스크립터
    • int level : 확인할 옵션의 프로토콜 레벨
    • int option_name : 확인할 옵션의 이름
    • void *restrict option_value : 확인 결과를 저장할 버퍼의 주소 값
    • socklen_t *restrict option_len : option_value로 전달된 주소 값의 버퍼 크기를 담고있는 변수의 주소 값
  • 반환 :
    • 성공 시, 0 반환
    • 실패 시, -1 반환
프로토콜 레벨옵션명getset내용
SOL_SOCKET (일반)SO_SNDBUFOKOK소켓 송신 버퍼의 크기
SOL_SOCKET (일반)SO_RCVBUFOKOK소켓 입력 버퍼의 크기
SOL_SOCKET (일반)SO_REUSEADDROKOK이미 사용 중인 주소나 포트에 대해서도 바인드 허용
SOL_SOCKET (일반)SO_KEEPALIVEOKOKkeepalive 메세지 활성화
SOL_SOCKET (일반)SO_TYPEOKX소켓의 타입 (ex: SOCK_STREAM)

6. bind

소켓에 주소(서버의 정보)를 할당(묶어줌)

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
  • 인자 :
    • int sockfd : 생성한 소켓 디스크립터
    • const struct sockaddr *addr : 소켓의 구조체 포인터(자신의 주소와 포트번호 들어있음)
    • socklen_t addrlen : 구조체의 길이
  • 반환 :
    • 성공 시, 0 반환
    • 실패 시, -1 반환

7. listen

서버가 bind한 뒤 어떤 클라이언트로부터 요청이 와도 수락할 수 있게 대기상태에 들어감

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : int listen(int socket, int backlog)
  • 인자 :
    • int socket : 소켓 디스크립터
    • int backlog : 연결 대기열의 크기 지정
  • 반환 :
    • 성공 시, 0 반환
    • 실패 시, -1 반환

8. accept

서버 소켓이 클라이언트의 요청을 받아들여 연결

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len)
  • 인자 :
    • int socket : 소켓 디스크립터
    • struct sockaddr *restrict address : 클라이언트 주소 정보를 담고 있는 구조체
    • socklen_t *restrict address_len : 구조체의 길이
  • 반환 :
    • 성공 시, 새로운 소켓 생성 후 해당 소켓 디스크립터 반환
    • 실패 시, -1 반환

9. send

소켓에서 메세지 보내기

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : ssize_t send(int socket, const void *buffer, size_t length, int flags)
  • 인자 :
    • int socket : 데이터를 보낼 대상의 소켓 디스크립터
    • const void *buffer : 보낼 데이터
    • size_t length : 데이터의 길이
    • int flags : 함수 호출 시 옵션을 사용하기 위한 플래그 (보통 0)
  • 반환 :
    • 성공 시, 보낸 바이트 수 반환
    • 실패 시, -1 반환

10. recv

소켓에서 메세지 받기

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : ssize_t recv(int socket, void *buffer, size_t length, int flags)
  • 인자 :
    • int socket : 데이터를 받을 대상의 소켓 디스크립터
    • void *buffer : 받을 데이터
    • size_t length : 데이터의 길이
    • int flags : 함수 호출 시 옵션을 사용하기 위한 플래그 (보통 0)
  • 반환 :
    • 성공 시, 받은 바이트 수 반환
    • 실패 시, -1 반환

11. connect

서버에 연결 요청

  • 헤더 :
    • #include <sys/socket.h>
    • #include <sys/types.h>
  • 형식 : int connect(int socket, const struct sockaddr *address, socklen_t address_len)
  • 인자 :
    • int socket : 연결하고자 하는 소켓 디스크립터
    • const struct sockaddr *address : 접속하고자 하는 IP와 포트 정보가 들어있는 구조체
    • socklen_t address_len : 구조체의 길이
  • 반환 :
    • 성공 시, 0 반환
    • 실패 시, -1 반환

12. fcntl

파일속성 변경

  • 헤더 : #include <fcntl.h>
  • 형식 : int fcntl(int fildes, int cmd, ...)
  • 인자 :
    • int fildes : 속성을 조회하거나 변경할 파일 디스크립터
    • int cmd : 제어 동작 명령
  • 반환 :
    • 성공 시, cmd에 따라 다름
    • 실패 시, -1 반환
cmd내용
F_GETFLfd에 대한 파일 상태 속성들을 반환값으로 돌려줌
F_SETFL파일 상태 속성들을 세번째 인자로 받아 설정
F_GETOWN현재 SIGIO, SIGURG 신호를 받도록 설정된 프로세스 ID 혹은 프로세스 그룹 ID를 돌려줌
F_SETOWNSIGIO와 SIGURG신호를 받도록 시정된 프로세스 ID나 프로세스 그룹 ID를 설정
F_DUPFD파일 서술자 fd를 복제, 새 파일 서술자 반환
F_DUPFD_CLOEXEC파일 서술자를 복제하고 새 파일 서술자에 관련된 FD_CLOEXEC를 설정, 새 파일 서술자 반환
F_GETFDfd에 대한 파일 서술자 플래그들을 반환
F_SETFD세번째 인자로 서술자 플래그들을 설정

13. kqueue

새로운 kernel event queue를 생성

  • 헤더 :
    • #include <sys/types.h>
    • #include <sys/event.h>
    • #include <sys/time.h>
  • 형식 : int kqueue(void)
  • 반환 :
    • 성공 시, 생성한 큐의 디스크립터 반환
    • 실패 시, -1 반환

14. kevent

  • 헤더 :
    • #include <sys/types.h>
    • #include <sys/event.h>
    • #include <sys/time.h>
  • 형식 : int kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout)
  • 인자 :
    • int kq : kqueue의 디스크립터
    • const struct kevent *changelist : 추가하거나 바꿀 이벤트의 리스트
    • int nchanges : 이벤트의 개수
    • struct kevent *eventlist : 이벤트를 받으면 커널에서 이벤트를 넣어주는 배열
    • int nevents : eventlist의 kevent의 배열의 수
    • const struct timespec *timeout : 기다리는 시간 (NULL -> 무한대기)
  • 반환 :
    • 성공 시, eventlist에 들어간 이벤트의(발생한 이벤트의) 수 반환
    • 실패 시, -1 반환
    • 타임 아웃 시, 0 반환

Reference

profile
블록체인 개발 어때요

0개의 댓글