QNX RTOS: 5-3. Client Information Structure
2025. 12. 2. 16:33ㆍ운영체제/QNX
1. Client Information Structure 개요
- 문제의식
- 서버 입장: “지금 나한테 MsgSend()한 클라이언트가 누구인지 / 어떤 버퍼 크기를 가지고 있는지 / 어떤 권한을 가진 프로세스인지 알고 싶다.”
- 어디서 정보를 얻는가?
- MsgReceive()의 4번째 인자에 _msg_info 구조체 포인터를 넘기면,
→ 커널이 메시지 수신과 동시에 클라이언트 정보를 채워줌. - 지금까지는 주로 NULL 로 넘겼는데,
이 자리에 _msg_info를 넘기면 클라이언트 정보까지 같이 얻는 것.
- MsgReceive()의 4번째 인자에 _msg_info 구조체 포인터를 넘기면,
struct _msg_info info;
rcvid = MsgReceive(chid, &msg, sizeof(msg), &info);

- 중요:
- 메시지에 대해서만 info가 업데이트됨.
- Pulse에 대해서는 info가 갱신되지 않음 → 이전 값이나 쓰레기값일 수 있음.
2. _msg_info에 들어있는 정보들
_msg_info는 “클라이언트에 대한 메타데이터”를 담는 구조체:

- 프로세스/스레드 정보
- pid : MsgSend()를 호출한 클라이언트 프로세스 ID
- tid : MsgSend()를 호출한 클라이언트 스레드 ID
- 연결/채널 정보
- chid : 서버의 채널 ID
- coid : 클라이언트 입장에서는 “내가 서버에 붙어 있는 Connection ID”
- scoid: 서버가 클라이언트를 식별하기 위한 Connection ID (Server Connection ID)
→ 서버 내부에서 “이 클라이언트 핸들”처럼 쓰는 ID
- 우선순위 및 플래그
- priority : 해당 메시지를 보낸 클라이언트 스레드의 우선순위
→ 서버 스레드는 일반적으로 이 priority로 동작 (QNX의 IPC 특징) - flags : 메시지/연결과 관련된 여러 플래그
- priority : 해당 메시지를 보낸 클라이언트 스레드의 우선순위
- 메시지 길이 정보
- msglen (source message length)
- 클라이언트가 보낸 메시지의 실제 길이
- dstmsglen (destination message length)
- 클라이언트가 reply를 받을 때 사용할 버퍼의 크기
- msglen (source message length)
- 이 길이 정보를 통해:
- 커널은 “둘 중 더 작은 길이만큼만” 복사
- send 시: min(보낸 길이, 서버 수신 버퍼 길이)
- reply 시: min(서버가 보내려는 길이, 클라이언트 reply 버퍼 길이)
- 서버는 dstmsglen을 보고:
- “클라이언트가 reply를 최대 몇 바이트까지 받을 수 있는지” 를 알 수 있음.
- 커널은 “둘 중 더 작은 길이만큼만” 복사

3. scoid(Server Connection ID)의 의미와 사용
3.1 scoid란?
- 서버 입장에서:
- “이 클라이언트 연결을 가리키는 인덱스/핸들” 같은 것
- internal connection table에서 해당 클라이언트 데이터를 찾을 때 키로 쓰기 좋음.
3.2 활용 예시
- 리소스 테이블 관리
- 서버가 scoid를 key로 해서
- 각 클라이언트별 상태, open된 리소스 정보, 통계 등을 저장
- 클라이언트가 종료되거나 disconnect 되면:
- 해당 scoid에 대응되는 구조체/리소스를 정리(cleanup)
- 서버가 scoid를 key로 해서
- 인증/접근 제어
- 서버가 “누가 나에게 메세지를 보냈는가?”를 scoid 기준으로 관리
- 특정 클라이언트만 허용하거나,
블랙리스트/화이트리스트 관리에 사용할 수 있음.
4. ConnectClientInfo() – 추가 정보를 알고 싶을 때
- _msg_info로도 충분한 정보가 있지만,
서버가 더 많은 인증 정보를 원할 수 있음:- 예: “이 클라이언트의 UID/GID가 무엇인지, 어떤 능력/권한이 있는지 알고 싶다”
- 이때 사용하는 함수가 ConnectClientInfo():
struct _client_info ci;
ConnectClientInfo(NULL, info.scoid, &ci, 0);
- 여기서 얻을 수 있는 정보:
- uid, gid
- supplemental group, capabilities(ability)
- 기타 보안 관련 정보
- 활용:
- 특정 UID만 허용
- 특정 group에 속한 프로세스만 접속 허용 등
- “권한이 없는 클라이언트의 요청은 MsgError()로 거절” 같은 정책 구현
5. _msg_info의 실전 활용 포인트
5.1 데이터 검증 & Reply 공간 검증
- 데이터 검증
- 요청 메시지 헤더에 “이만큼의 데이터를 달라”고 적혀 있지만,
- 실제 클라이언트의 send 길이/버퍼가 이상할 수 있음.
- _msg_info의 msglen을 보고:
- “클라이언트가 실제로 얼마나 보내왔는지”를 확인
- 범위를 넘어선 요청을 방어 (out-of-bounds 방지)
- reply 공간 체크
- 서버가 많은 데이터를 보내고 싶을 때:
- _msg_info.dstmsglen으로
- “클라이언트 reply 버퍼 크기” 확인
- 그 크기를 넘지 않도록 잘라서 보내거나,
- 부족하면 에러/부분전송 처리
- _msg_info.dstmsglen으로
- 서버가 많은 데이터를 보내고 싶을 때:
5.2 로깅 및 디버깅
- _msg_info의 pid, tid를 이용해서:
- “어떤 프로세스/스레드가 어떤 요청을 보냈는지” 로그에 남김
- 장애 상황/성능 분석 시 매우 유용:
- 예: 특정 PID가 비정상적으로 많은 요청을 보낸다
- 실시간/안전 시스템에서:
- “특정 클라이언트의 과도한 요청 → 서버 응답 지연” 같은 이슈 추적에 도움
6. 정리
- MsgReceive()의 4번째 인자(기존에 NULL로 두던 것)는
클라이언트 메타데이터를 담는 _msg_info 구조체 주소를 넘기는 자리. - 이 구조체를 통해:
- 누가 보냈는지 (PID/TID, scoid, priority)
- 얼마나 보냈고, 얼마나 돌려줄 수 있는지 (msglen, dstmsglen)
- 추가 인증 정보로 연결할 수 있는 키(scoid) 를 얻을 수 있음.
- Pulse는 이 구조가 업데이트되지 않는다는 점이 중요 포인트.
- 이후에 ConnectClientInfo()와 연계하면
→ IPC + 보안/인증 + 로깅까지 통합된 서버 설계가 가능해짐.
'운영체제 > QNX' 카테고리의 다른 글
| QNX RTOS: 5-5. Multi-Part Messages (0) | 2025.12.02 |
|---|---|
| QNX RTOS: 5-4. How a Client Finds a Server (0) | 2025.12.02 |
| QNX RTOS: 5-2. Pulses (0) | 2025.12.02 |
| QNX RTOS: 5-1. Message Passing (0) | 2025.11.27 |
| QNX RTOS: 5. Interprocess Communication (0) | 2025.11.27 |