Unix

Pidgin-nateon 파일 전송기능 수정 - 2

ForceCore 2011. 2. 14. 19:44
pidgin-nateon에서 xfer.c를 디벼보자...
프로그램 하나의 코드를 분석하는 것도 힘든데 양쪽을 다 알아야 한다니 ㅎㄷㄷ
게다가 기반 라이브러리가, 하나는 qt, 다른 하나는 gtk. 

static void nateon_xfer_init(PurpleXfer *xfer)
보아하니 이 함수에서 비슷한 짓을 하고 있는 것 같구만. (느낌에 의해 init으로 검색했다 ㅋㅋ)

그것을 콜하고 있는 함수도 하나 있다.
nateon_xfer_send_file(NateonSession *session, const char *who, const char *filename)

함수 이름이 맘에 드는군. "파일 보내라" 함수. -_-;; 이 함수에서는 여러가지 보내기에 필요한 이벤트 헨들링을 다 정의하고 있으니 파일 보내기에 대해선 거의 top level에 해당하는 듯.
"파일 보내기 배틀 신청"
수신 취소
파일 거절당함
전송완료
보내기 취소
를 다 담당할 함수를 지정해주고, 보낼 파일이 뭔지에 따라 적절한 purple library의 함수를 콜하는군... 흐음.

반대로 받는 함수도 있다.
void
nateon_xfer_receive_file(NateonSession *session, NateonSwitchBoard *swboard, \
const char *who, const char *filename, const int filesize, const char *cookie)

하지만 일단 그건 나중으로 미룬다.

배틀신청 함수가 아까 언급한 xfer_init이고... 이거부터 손봐주겠다. 에... 이게 파일 수신 코드도 같이 들어있네 OTL 그래도 무슨 생각이 있거나, convention이 있어서 (다른 M$N이나 다른 메신저 프로토콜도 그랬다든지) 이렇게 구현되어 있겠지 (아마도). PurpleXfer라는 struct 모양만 봐도 그런 추측이 가능하다.

else if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)
이 부분이 보내기 요청하는 부분이다... 이 부분은 잘 된 것 같은데?;;;;;
실제로 멀쩡하고, 디버그 창에 뜨는 메시지를 보면,
(18:44:55) nateon: C: SB 001: WHSP 2 xxx@nate.com FILE REQUEST%091%09xxx.pdf|78609|488:10026452103:122
(18:44:55) nateon: S: SB 001: WHSP 0 xxx@nate.com FILE UNKNOWN%091%09xxx.pdf|78609|488:10026452103:122
(18:44:55) nateon: [whsp_cmd]http://xxx.xx.114.xx:8080/
(18:44:58) nateon: S: SB 001: SPSH 0 HARDWARN 대화%20참여자의%20일부%20또는%20전체와%20호환되지%20않는%20버전으로%20요청하신%20기능을%20실행%20할%20수%20없습니다.%20최신버전으로%20업그레이드%20후%20이용해%20주세요. A060
이런 것이 뜬다.

파일 수신부를 먼저 해봐야 하나. 먼저랄것도 없이, 최초 전송 리퀘가 있은 뒤 네톤에서 무슨 짓을 하는지 알아봐야 한다.

운 좋게도;; 네톤 함수 중
bool ChatView::parseCommand(const QStringList & slCommand)
마침 이 함수를 보고 있었는데 (왜냐면 REQUEST로 검색을 했었다) 저기에서 gotFILE_REQUEST를 보면 되겠군. 피진에서 보낸 리퀘가 slCommand로 간 것이다.

아무래도 피진 네톤 만드신 분의 말을 들어봐야 할 듯 하다. 맨땅에 헤딩 할 이유가 없지.. p2p로만 되는 것도 아니고 중간에 무슨 서버를 거치게 되어있기 때문에 파일전송 쪽 코드만 봐도 안된다 -_-;;

S: SB 는 서버에서 나한테 보냈단 것이다?
C: SB는 내가 서버한테 보냈단 것이다? 읭? 아닌거 같은데. 뭐지. 어쨌든 첫 줄이 내가 chat session에 보낸 거라는군. SB는 chat session이니깐... S는 서버로 해석하고... 대충 이해가 될랑 말랑

서버/상대/나 3자가 얽혀 있기 때문에, 인터페이스만 간단히 조절했던 저번의 쪽지 답장버튼 추가와는 난이도의 차원이 다르다 -_-;;

중간에서 서버가 내 말을 알아먹었으면 아마도 CTOC 머시기 이런 메시지가 오는 모양인데, 서버를 어떻게 해야 하누... 혹시 로그인 시에 클라이언트 버전을 보내는 부분이 있을지도 모르겠군. 프로토콜은 아직 호환될 것 같은데 -_-;;;

확실히, 로그인시 PVER를 통해 버전을 보낸다.
PVER 1 3.615 3.0\r\n
이 부분이 달라져있다.

PVER 0 1.1.0.301 3.0 ko.linuxm

이라고 되는군. 뭐... 그대로 일단 반영해봐야겠다.

NateonConnection::dataReceived 함수와
void NateonConnection::writeData(const QString& sData) 함수에다가
cout -_-;; 으로 주고 받는 데이터가 보이도록 코드를 바꿨다. 이미 적혀있는 문서와 거의 유사하다.
이쪽은 네톤쪽 서버와 주고 받는 데이터를 나타나게 하는 것이라 채팅창의 데이터 프로토콜은 안 보인다. 하지만 채팅은 멀쩡하게 되는 것으로 보아서는 채팅 프로토콜도 해킹해서 바꾸진 않아도 그다지 상관 없을 듯. -ㅠ- 끙

>>> PVER 6 1.1.0.301 3.0 ko.linuxm

<<< PVER 6 N
>>> AUTH 7 DES

<<< AUTH 7 DES
>>> REQS 8 DES xxx@nate.com

<<< REQS 8 dpc_012:19743 [서버IP?] 5004

>>> ONST 4 X 0 %00 1

>>> LSIN 5 개인정보 보내고

<<< LSIN 5 티켓 오고
>>> LOPT 6 TXT 15
memo_wnd_show=1
<<< LOPT 6 0

대충 로그인 시퀀스는 이렇다. ONST 어쩌구 이 부분이 이증 시작일거 같음.
LSIN은 인증 부분으로서
이 문서를 따르면 된다. 로그인 시퀀스도 그다지 달라진 부분은 없는데, PVER만 좀 다른거 같음.

static void
connect_cb(NateonServConn *servconn)
피진에서, 여기에 보면 PVER를 보내는 코드가 있다. 좀 손봐준다. 리눅스용 네이트온과 동일하게 했다 -_-;

AUTH에도 보면 버전을 보내는 부분이 있다. 샒;; 사실 LOGIN 요청에 보내는 버전/lang/os 정보는 무시되는 듯.
void NateonDPConnection::putLSIN() 에서 보내는 LSIN 메시지를 만들어 내는듯.
PVER에서 보낸 정보가 무시되는걸 어떻게 알았냐면. nateon 클라이언트에서, 피진이 ko.windows 로 인식되고 있더라 -_-;; 피진에서 상태변경을 하면 네톤에서 내 정보가 가면서 운영체제 정보가 같이 간다. (대체 왜?)

연구한 결과, https:// 로 이상한 접속을 해서 SSL티켓을 따온 이후에, putLSIN이 그 티켓을 이용하여 다시 로그인 요청을 하는 모양이다 -_-;;; 혼자서는 도저히 안 되겠고, 아마 이런 비슷한 방식을 쓰는 데가 있을텐데... pidgin 전체 소스코드를 받아서 여러 프로토콜 중 https 로 티켓 따내는 게 있나 체크해봤더니 야후가 그렇게 하는 듯.

yahoo_auth16_stage1
이 함수에서 URL로 뭔가 id/비번을 보내서 뭔가 받아내는듯.
purple_util_fetch_url_request_len_with_account
이런 긴 이름을 가진 함수를 통해서 데이터를 받아오는데, 그 데이터가 돌아오는 시점에서 콜백함수가 호출되는 듯. 즉... 현재 구현되어 있는 네톤의 인증 stage보다 stage수가 하나 증가해야 한단 것이다.

yahoo_process_auth
이 함수가 인증과정을 다루는 함수일... 까? top level은 아닐지라도 시작부분을 담당하는 건 어느정도 맞는 듯 하다. 계속 콜백이 이어지면서 auth 단계가 넘어가는 듯. 콜백이 아니더라도, 다름 stage의 함수를 적절히 콜한다. pidgin-nateon의 현재 구현을 보면 FSM처럼 보이기도 하지만, 그렇게 되려다 포기한 듯. 야후 것을 컨닝하니 길이 보여서 적절히 구현하니 로그인 성공 (-_-...) 간단히 썼지만 어제부터 작업한 시간을 따지면 한 24시간 걸린듯 (잠자는 시간 먹는 시간 포함 -_-)

이제 로그인시 보내는 클라이언트 정보는 속였고... 그래도 덜 속인게 있는지, 피진에서 네톤으로 파일 보내려고 하면 기능 없다고 아직도 뭐라 한다. 다시 원점이군.

하지만 클라이언트 정보가 바뀐 탓에, 대화도 나눌 수 없는 상태가 되었다 ㅎㄷㄷ 쪽지도 안 된다. 파일전송 "만" 짜야 하는 게 아니라 전체를 다 뜯어고쳐야 하는 상태라니 매우 우울하다. 그리고 로그아웃해도 튕긴다. 다행해도 상태변경은 프로토콜이 안 바뀌어서 먹힌다 -_-;;;;

로그인 시 오는 요청 중 MCNT란게 있는데, 이게 다중접속 상태를 나한테 알려주는 부분이다. 일단은 무시할래.

<<< MCNT 0 O 1 0
>>> MLST 7 xxx@nate.com 0^M
로그인시

<<< MLST 7 xxx@nate.com 1 57
<<< NTFY 0 xxx@nate.com O 0 %00 1 ko.linuxm
<<< MCNT 0 O 2 0
>>> MLST 8 xxx@nate.com 0^M
한명이 더 접속했음.

<<< MLST 8 xxx@nate.com 2 122
<<< SMSG 0 xxx@nate.com 982
<<< MCNT 0 F 1 0
추가접속한 사람이 나갔음.

이렇게 되어 있군. 현재로서는 무시해도 될 듯 한데...

친구 목록 보이기 같은 부분도 일단은 멀쩡하다. 안 되는것만 보기보단 긍정적으로 보자 (-_-)

안 되는거: 메모, 채팅, 파일 보내기, 정보 가져오기/SMS 보내기/다중 접속 밖에(?) 없다.
그나마도 많이는 안 바뀌었을 것 같은데 (?). 아마 내 생각엔, 다중접속 기능 때문에 어느 메시지가 어느 클라리언트한테 가는지 중재하는 것 때문에 이거저거 좀 건드려 졌을 듯.

되는것: 차단/상태변경/로그인/로그아웃(?)/그룹 바꾸기/친구 추가,삭제(? 자주 일어나는 일이 아니라 잘 모르겠다)

채팅부터 해보지 뭐.

에... 내가 추측할 필요 없이 네톤 소소코드 안에 doc 폴더안에 프로토콜에 대한 설명이 어느정도 있다. 헐;; 근데 좀 outdate 된 듯 함.

채팅부터 수정... 아니 다중접속을 하게 되는 상황에서, 피진이 다짜고짜 튕기는 것 부터 어떻게 해야겠다. 네톤/피진이 동시에 로그인 한 경우 말이다. 너무 순식간이라 모르지만...


여기 나오는대로 back trace를 해보면... 그거 하기도 전에. 쪽지가 오면서 튕기는듯. 쪽지 기능이 망가져서 튕기는건가 -_-;;; 여러모로 모든게 얽혀있어서 짜증나는군.

1. 다중접속 발생
2. 서버에서 나한테 다중접속 되었다고 쪽지 옴
3. 쪽지 기능때문에 튕김?
이렇게 되는 듯.

#0  nateon_command_from_string (string=<value optimized out>) at command.c:67
        param = 0x0
        c = <value optimized out>
        cmd = 0xe12f10
        tmp = 0xa19480 "font-style:"
        param_start = <value optimized out>
        __PRETTY_FUNCTION__ = "nateon_command_from_string"
#1  0x00007fffe5157a3b in nateon_cmdproc_process_cmd_text (cmdproc=0xe29930, 
    command=0xe63a24 "font-style: ") at cmdproc.c:332
No locals.
#2  0x00007fffe515e087 in read_cb (data=0xe299f0, 
    source=<value optimized out>, cond=<value optimized out>)
    at servconn.c:456
        servconn = 0xe299f0
        session = <value optimized out>
        buf = "SMSG 0 yyy@nate.com 1010\r\nIMSG\r\nconfirm:0\r\ncontenttype:text\r\ncookie:1sX0a-nVuRt15R9t1CWkztH002CVYaUQNiahl0tX6-Q7YTaMbSSe_dX27BAKB5WS\r\ndate:20110215164910\r\nfont-color:#000000\r\nfont-name:굴림\r\nfont-"...
        cur = 0xe63a24 "font-style: "
        end = 0xe63a32 "from:nateonmaster@nate.com\r\nlength:643\r\nref:yyy@nate.com\r\nrelated:N\r\nsource:web\r\ntitle:[다중접속%20안내]\r\nuuid:NEW-UUID-605013929651\r\n\r\n[다중접속 안내]\r\n같은 아이디로 동시에"...
        old_rx_buf = 0xe63950 "SMSG 0 yyy@nate.com 1010"
        len = <value optimized out>
        cur_len = <value optimized out>
헴... 별로 도움이 안 된다. -_-;;

pidgin -d
로 실행하면, 디버그창에 떠야 하는 정보가 콘솔로 뜬다. 이거면 왜 튕기는지 힌트를 얻기 수월하다.
(17:07:10) g_log: nateon_userlist_find_user_with_name: assertion `account_name != NULL' failed
(17:07:10) g_log: nateon_user_get_store_name: assertion `user != NULL' failed
(17:07:10) g_log: nateon_userlist_find_user_with_name: assertion `account_name != NULL' failed
(17:07:10) g_log: nateon_user_get_friendly_name: assertion `user != NULL' failed
쪽지 보낸 놈이 관리자라서, 내 친구 목록에 없고, 유저명을 밝히는 건 더더욱 불가능해서 이런 일이 벌어지는 것 같다.

nateonmaster@nate.com
이 것을 예외처리해서 더럽게 처리해야 하나... 흐음;

메모 프로토콜이 바뀌었는데 어떻게 처리해야할지 프로토콜을 몰라서 감이 안 온다. 네톤을 개조하기도 지쳤다. 디버그 기능을 켜서 컴파일 하는 게 좋을 듯. CMakeLists.txt에
ADD_DEFINITIONS(-DDEBUG)
ADD_DEFINITIONS(-DNETDEBUG)
를 넣고 컴파일 다시 시켰다. 오오 매우 잘 됨.

IMSG
confirm:0
contenttype:text
cookie:ZhXmtoVLyBy3UjJXiuinQEpfJdf4pOyMxaMHs9Tv4p_jlEkEcuuAJS7y4czZEHhf
date:20110215174218
font-color:#000000
font-name:굴림
font-size:9
font-style: 
from:nateonmaster@nate.com
length:643
ref:yyy@nate.com
related:N
source:web
title:[ë‹¤ì¤‘ì ‘ì†%20안내]

[ë‹¤ì¤‘ì ‘ì† 안내]
같은 아이디로 동시에 2개이상의 네이트온에 로그인되어 있습니다.
다른 곳에서 ì ‘ì†í•œ 네이트온 IPì •ë³´ìž…ë‹ˆë‹¤.

컴퓨터 : yyy@ubuntu (IP : 121.135.151.126)

여러곳에서 로그인 된 경우 일부 대화, 쪽지 내용이 다른 네이트온에 표시 ë  ìˆ˜ 있습니다.
사용하지 않는 네이트온은 로그아웃 해주세요.

<link href='http://erms.nate.com/faq/exSelfFAQA.jsp?PageNo=1&nodeId=NODE0000000683&parentNodeId=NODE0000000940&grandParentNodeId=&nodeDepth=4&checkFaq=0&faqId=FAQS0000009533&index=1'>☞ 다중 ì ‘ì† 자세히 보기</link>
(2011-02-15 17:41:54) <-- MLST 9 yyy@nate.com 2 122
dpc_01201:19744|bwzc 1 3 ko.linuxm jdj@arin 컴퓨터 1
dpc_01004:23616|vluQ 1 3 ko.linuxm yyy@ubuntu 컴퓨터 1
쪽지가 뭐 이리 길다냐. 일반 쪽지는 CMSG 명령 이후에 오는데 얘는 SMSG 명령 이후에 와서 그런 것 같다? 그런듯. 맞네. CMSG와 유사하게 SMSG도 처리하는 루틴을 넣어주면 될 것 같다.... CMSG 처리하는 루틴이 없는거 같다? 아예 없구나... CMSG에서 좀 긴 메시지가 오면 그거를 적절히 수신해서 명령 해독하고... 그런 코드가 필요함. SMSG도 마찬가지. 문제는, 얘네들은 명령 중간에 \r\n이 들어간다는 점이다.

read_cb
여기에서, \r\n 으로 끊어주는 코드가 등장한다.
다행히도... last_cmd 라는 항목이 있어서 직전 명령어가 뭐였는지 (SMSG인지, CMSG인지) 살펴보고 대처하는 것도 가능할 것 같다. 이걸 사용하는 곳은 아직 없는 듯 하지만... 원래 pidgin-nateon 만드신 분이 굉장히 잘 만들어 두신 것이다. 나라면 당장 필요 없다고 안 만들어뒀을텐데 -_-;;

last_cmd 항목을 적절히 이용해서 로그인 하자마자 튕기는건 처리했다. 호오... 하지만 그 뒤에 나타나는 명령어는 처리를 영 못 하는 것 같군. (친구 드갔다 나갔다 하는거). 그리고 적절한 수작을 부려서 IMSG를 적절히 분리하는 코드를 만들었다. 분리 해내니깐 IMSG 명령을 잘 해석하지 못하는군.