cmsg(3) - wariua/manpages-ko GitHub Wiki
CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - ๋ณด์กฐ ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ธฐ
#include <sys/socket.h>
struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh,
struct cmsghdr *cmsg);
size_t CMSG_ALIGN(size_t length);
size_t CMSG_SPACE(size_t length);
size_t CMSG_LEN(size_t length);
unsigned char *CMSG_DATA(struct cmsghdr *cmsg);
์ด ๋งคํฌ๋ก๋ค์ ์ฌ์ฉํด ์์ผ ํ์ด๋ก๋์ ํฌํจ๋์ง ์๋ ์ ์ด ๋ฉ์์ง(๋ณด์กฐ ๋ฐ์ดํฐ๋ผ๊ณ ๋ ํจ)๋ฅผ ์์ฑํ๊ณ ์ ๊ทผํ๋ค. ๊ทธ๋ฐ ์ ์ด ์ ๋ณด์๋ ํจํท์ ๋ฐ์ ์ธํฐํ์ด์ค, ๋๋ฌผ๊ฒ ์ฐ์ด๋ ์ฌ๋ฌ ํค๋ ํ๋๋ค, ํ์ฅ ์ค๋ฅ ์์ , ํ์ผ ๋์คํฌ๋ฆฝํฐ, ์ ๋์ค ํฌ๋ฆฌ๋ด์ ์งํฉ์ด ํฌํจ๋ ์ ์๋ค. ์๋ฅผ ๋ค์ด ์ ์ด ๋ฉ์์ง๋ฅผ ์ฌ์ฉํด IP ์ต์ ๊ฐ์ ์ถ๊ฐ์ ์ธ ํค๋ ํ๋๋ฅผ ๋ณด๋ผ ์ ์๋ค. sendmsg(2)๋ฅผ ํธ์ถํด์ ๋ณด์กฐ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ณ recvmsg(2)๋ฅผ ํธ์ถํด์ ๋ฐ๋๋ค. ์์ธํ ๋ด์ฉ์ ๊ฐ ๋งค๋ด์ผ ํ์ด์ง๋ค์ ๋ณด๋ผ.
๋ณด์กฐ ๋ฐ์ดํฐ๋ cmsghdr
๊ตฌ์กฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ถ์ธ ๊ฒ๋ค์ ๋ฐฐ์ด์ด๋ค. ์ฌ์ฉ ๊ฐ๋ฅํ ์ ์ด ๋ฉ์์ง ํ์
์ ๋ํด์ ๊ฐ๋ณ ํ๋กํ ์ฝ ๋งจ ํ์ด์ง๋ฅผ ๋ณด๋ผ. ์์ผ๋ณ ๋ณด์กฐ ๋ฒํผ ์ต๋ ํฌ๊ธฐ๋ฅผ /proc/sys/net/core/optmem_max
๋ก ์ค์ ํ ์ ์๋ค. socket(7) ์ฐธ๊ณ .
cmsghdr
๊ตฌ์กฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋์ด ์๋ค.
struct cmsghdr {
size_t cmsg_len; /* ๋ฐ์ดํฐ ๋ฐ์ดํธ ๊ฐ์. ํค๋ ํฌํจ.
(POSIX์์๋ ํ์
์ด socklen_t) */
int cmsg_level; /* ๊ธฐ์ ํ๋กํ ์ฝ */
int cmsg_type; /* ํ๋กํ ์ฝ๋ณ ํ์
*/
/* ์ด์ด์:
unsigned char cmsg_data[]; */
};
cmsghdr
๊ตฌ์กฐ์ฒด ์ด์ ์ ๋๋ก ์ง์ ์ ๊ทผํ์ง ๋ง์์ผ ํ๋ค. ๋์ ๋ค์ ๋งคํฌ๋ก๋ค์ ์ฌ์ฉํ๋ผ.
-
CMSG_FIRSTHDR()
๋ ์ ๋ฌ๋ฐ์msghdr
์ ์ฐ๊ณ๋ ๋ณด์กฐ ๋ฐ์ดํฐ ๋ฒํผ์ ์ฒซ ๋ฒ์งธcmsghdr
์ ๋ํ ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ค. ๋ฒํผ์cmsghdr
๊ฐ ๋ค์ด๊ฐ ๊ณต๊ฐ์ด ์์ผ๋ฉด NULL์ ๋ฐํํ๋ค. -
CMSG_NXTHDR()
๋ ์ ๋ฌ๋ฐ์cmsghdr
๋ค์์ ์ ํจํcmsghdr
๋ฅผ ๋ฐํํ๋ค. ๋ฒํผ์ ์ถฉ๋ถํ ๊ณต๊ฐ์ด ๋จ์ ์์ง ์์ผ๋ฉด NULL์ ๋ฐํํ๋ค.(๊ฐ๋ น sendmsg(2)๋ก ๋ณด๋ผ) ์ผ๋ จ์
cmsghdr
๊ตฌ์กฐ์ฒด๋ฅผ ๋ด์ ๋ฒํผ๋ฅผ ์ด๊ธฐํ ํ ๋๋CMSG_NXTHDR()
์ ์ฌ๋ฐ๋ฅธ ๋์์ ์ํด ๋จผ์ ๋ฒํผ๋ฅผ 0์ผ๋ก ์ด๊ธฐํ ํ๋ ๊ฒ ์ข๋ค. -
CMSG_ALIGN()
์ ๊ธธ์ด๋ฅผ ๋ฐ์์ ํ์ ์ ๋ ฌ์ ๊ฐ์ํ ๊ธธ์ด๋ฅผ ๋ฐํํ๋ค. ์์ ์์ด๋ค. -
CMSG_SPACE()
๋ ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ ๊ธธ์ด์ ํ์ด๋ก๋๋ฅผ ๊ฐ์ง ๋ณด์กฐ ํญ๋ชฉ์ด ์ฐจ์งํ๋ ๋ฐ์ดํธ ์๋ฅผ ๋ฐํํ๋ค. ์์ ์์ด๋ค. -
CMSG_DATA()
๋cmsghdr
์ ๋ฐ์ดํฐ ๋ถ๋ถ์ ๋ํ ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ค. -
CMSG_LEN()
์cmsghdr
๊ตฌ์กฐ์ฒด์cmsg_len
๋ฉค๋ฒ์ ์ ์ฅํ ๊ฐ์ ๋ฐํํ๋๋ฐ, ํ์ํ ์ ๋ ฌ๊น์ง ๊ณ ๋ คํ ๊ฐ์ด๋ค. ๋ฐ์ดํฐ ๊ธธ์ด๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค. ์์ ์์ด๋ค.
๋ณด์กฐ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค๋ ค๋ฉด ๋จผ์ msghdr
์ msg_controllen
๋ฉค๋ฒ๋ฅผ ์ ์ด ๋ฉ์์ง ๋ฒํผ์ ๊ธธ์ด๋ก ์ด๊ธฐํ ํด์ผ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ msghdr
์ CMSG_FIRSTHDR()
๋ฅผ ์ฌ์ฉํด ์ฒซ ๋ฒ์งธ ์ ์ด ๋ฉ์์ง๋ฅผ ์ป๊ณ CMSG_NXTHDR()
๋ก ์ดํ ๋ฉ์์ง๋ค์ ์ป๋๋ค. ๊ฐ ์ ์ด ๋ฉ์์ง์์ (CMSG_LEN()
์ผ๋ก) cmsg_len
์, ๋ค๋ฅธ cmsghdr
ํค๋ ํ๋๋ค์, ๊ทธ๋ฆฌ๊ณ CMSG_DATA()
๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ ๋ถ๋ถ์ ์ด๊ธฐํ ํ๋ค. ๋ง์ง๋ง์ผ๋ก msghdr
์ msg_controllen
ํ๋๋ฅผ ๋ฒํผ ๋ด ๋ชจ๋ ์ ์ด ๋ฉ์์ง ๊ธธ์ด์ CMSG_SPACE()
์ ํฉ์ผ๋ก ์ค์ ํด์ผ ํ๋ค. msghdr
์ ๋ํ ์ถ๊ฐ ๋ด์ฉ์ recvmsg(2)๋ฅผ ์ฐธ๊ณ ํ๋ผ.
์ด ๋ณด์กฐ ๋ฐ์ดํฐ ๋ชจ๋ธ์ POSIX.1g ์ด์, 4.4BSD-Lite, RFC 2292์์ ๊ธฐ์ ํ๋ IPv6 ๊ณ ๊ธ API, SUSv2๋ฅผ ๋ฐ๋ฅธ๋ค. CMSG_ALIGN()
์ ๋ฆฌ๋
์ค ํ์ฅ์ด๋ค.
์ด์์ฑ์ ์ํด์ ์ฌ๊ธฐ ๊ธฐ์ ํ ๋งคํฌ๋ก๋ค๋ง ์ฌ์ฉํด ๋ณด์กฐ ๋ฐ์ดํฐ์ ์ ๊ทผํด์ผ ํ๋ค. CMSG_ALIGN()
์ ๋ฆฌ๋
์ค ํ์ฅ์ด๋ฏ๋ก ์ด์์ฑ์ด ์์ด์ผ ํ๋ ํ๋ก๊ทธ๋จ์์๋ ์ฌ์ฉํ์ง ๋ง์์ผ ํ๋ค.
๋ฆฌ๋
์ค์์ CMSG_LEN()
, CMSG_DATA()
, CMSG_ALIGN()
์ (์ธ์๊ฐ ์์๋ผ๊ณ ๊ฐ์ ์) ์์ ์์ด๊ณ , ๋ฐ๋ผ์ ์ ์ญ ๋ณ์ ํฌ๊ธฐ๋ฅผ ์ ์ธํ๋ ๋ฐ ๊ทธ ๊ฐ์ ์ธ ์ ์๋ค. ํ์ง๋ง ์ด์์ฑ์ด ์์ ์ ์๋ค.
๋ค์ ์ฝ๋์์๋ ๋ฐ์ ๋ณด์กฐ ๋ฒํผ์์ IP_TTL
์ต์
์ ์ฐพ๋๋ค.
struct msghdr msgh;
struct cmsghdr *cmsg;
int *ttlptr;
int received_ttl;
/* msgh์ ๋ณด์กฐ ๋ฐ์ดํฐ ๋ฐ๊ธฐ */
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
if (cmsg->cmsg_level == IPPROTO_IP
&& cmsg->cmsg_type == IP_TTL) {
ttlptr = (int *) CMSG_DATA(cmsg);
received_ttl = *ttlptr;
break;
}
}
if (cmsg == NULL) {
/* ์ค๋ฅ: IP_TTL์ ์ผ์ง ์์๊ฑฐ๋ ๋ฒํผ๊ฐ ์๊ฑฐ๋ I/O ์ค๋ฅ */
}
์๋ ์ฝ๋์์๋ SCM_RIGHTS
๋ฅผ ์ด์ฉํด ์ ๋์ค ๋๋ฉ์ธ ์์ผ ์์ผ๋ก ํ์ผ ๋์คํฌ๋ฆฝํฐ ๋ฐฐ์ด์ ์ ๋ฌํ๋ค.
struct msghdr msg = { 0 };
struct cmsghdr *cmsg;
int myfds[NUM_FD]; /* ์ ๋ฌํ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ๋ด์ */
char iobuf[1];
struct iovec io = {
.iov_base = iobuf,
.iov_len = sizeof(iobuf)
};
union { /* ๋ณด์กฐ ๋ฐ์ดํฐ ๋ฒํผ. ์ ์ ํ ์ ๋ ฌ๋๊ฒ
ํ๊ธฐ ์ํด ๊ณต์ฉ์ฒด๋ก ๊ฐ์ผ๋ค */
char buf[CMSG_SPACE(sizeof(myfds))];
struct cmsghdr align;
} u;
msg.msg_iov = &io;
msg.msg_iovlen = 1;
msg.msg_control = u.buf;
msg.msg_controllen = sizeof(u.buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
memcpy(CMSG_DATA(cmsg), myfds, NUM_FD * sizeof(int));
RFC 2292
2019-03-06