Unix

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

ForceCore 2011. 2. 16. 01:02
nateon_command_from_string 이거부터 할 차례. IMSG 를 잘 처리하지 못하였으므로.

CMSG처리가 아직 잘 안 되는 듯 하다. length 따지는 법이 맞나 틀리나도 모르겠거든!!;;

네톤 소스 중...
nateonconnection.cpp:362에 CMSG, PMSG(웹에서 보낸 쪽지!) SMSG 외 body + len + body 형식의 명령어가 뭐가 있나 적혀있다. 많기도 하네;; 하지만 무시.

CTOC가 이미 피진에 있음을 발견 ㅎㄷㄷ;; 이걸 CMSG, PMSG 등에도 이용할 수 있겠군. 내가 구현한 것은 제거. Mercurial같은 관리 프로그램을 이용해 중간중간 적절히 commit 해뒀기 때문에 쉽게 돌아갈 수 있었다.

CTOC 처리된 부분의 코드를 훔쳐봐야겠다.

그냥... SMSG나 CMSG모두 CTOC 처리기를 썼다 -_-; 그러면 IMSG가 분리되어 나오면서 알아서 돌기 시작한다. 다만 쪽지가 완벽하게 해독되어 뜨진 않네;;; 다중접속 알림 메모는 제대로 해독하지 못해서 보낸이+이름을 잘 못 해독하고, 내용도 무시해도 되는 부분까지 보여줘서 좀 탈이다. 메모 처리기를 조금 손봐줘야겠군...

왜 오작동하는지 보니깐 
IMSG
confirm:0
contenttype:text
cookie:qSHQ-qZlAmezVvXuCEY_NcAMIycn3FcgAmI5Oi
date:20110215213003
font-color:#000000
font-name:굴림
font-size:9
font-style: 
from:nateonmaster@nate.com
length:643
ref:xxx@nate.com
related:N
source:web
title:[다중접속%20안내]
font-style: 이게 빈칸이다 -_-;; 빈칸인데다가 눈에 보이진 않지만 공백이 들어가있다... 정말 미치게 하는군. ctoc_cmd_post 여기서 무차별적으로 공백을 다 parameter 끊는 식별자로 인식해서 쪼개버리기 때문에 발생한 버그이다. 그래도 IMSG 핸들러에서 어떻게든 알아서 하는 편이 나을 것 같음... 좋은 생각이 떠올랐다. " "로 쪼갰었으니까 도로 합쳤다 또 내가 원하는 방식으로 쪼개면 되지 -_-;; 그것도 좀... \n과 " "의 구분이 없이 다 토막을 내버렸기 때문에 곤란함. 차라리, uuid 이후가 내용이라고 가정해버리는게 가장 쉬운 편인 듯 하다. 뭐, 나중에 쪽지가 정상동작 안 하면 그때 손보기로 하고 일단은 가정을 넣어버리자.

음... 대충 해결 되었는데, 쪽지 내용의 \n을 잘 처리 못하게 되었군. 에... 헐. 일반유저가 보낸 건 잘 처리하는데 ;; 제길 who cares ㅋㅋ 문제를 무시하기로 한다 -_-;;;;;;

이제 또 문제는 뭐냐면. 쪽지를 받을 순 있다. 일반 유저가 보낸 것도 잘 받아진다. 근데, 쪽지를 보내기만 하면 튕긴다. -_-;;

--> CMSG 287 N 316
xxx@nate.com
IMSG
title:????
from:yyy@nate.com
ref:xxx@nate.com
date:20110215221427
session_id:658810
uuid:04d68b0c-f678-4c99-ab16-1e1fdb039577
contenttype:text
length:6
font-name:Arial
font-style:%00
font-size:9
font-color:#0a0a0a
ref-uuid:
cookie:
event:NW

우라카라
(2011-02-15 22:14:27) <-- CMSG 287 0
이게 보내야 하는 메시지고, CMSG 287 0 이라고 답신이 돌아와야 함. 얼레... uuid가 마지막이 아니네. 우울하다 -_-;; 왜 되는거지?! 서버에서 uuid를 만들어서 보내줘서 되는 것 같다. 휴;; 또 재미있는게, 전에는 웹에서 쪽지를 보내면 피진네톤이 튕겼는데 지금은 안 그렇다. (PMSG 처리를 해줬기 때문이다 훗)

보내면 생기는 문제를 처리해야 할듯.
필자는 튕기는 원인이, 서버에서 답신으로 돌아오는 CTOC명령때문일지도 모르겠다라고 일단 찍었다.
ctoc_cmd에 보면 딱히 문제는 없어 보이는데... 에...

(22:22:06) nateon: C: NS 000: CMSG 8 N 142
(22:22:06) nateon: S: NS 000: CMSG 8 0
(22:22:06) nateon: [ctoc_cmd]
Pidgin 2.7.10 has segfaulted and attempted to dump a core file.

흐음. 전에는 되돌아오는 CMSG를 쿨하게 무시했었군. 지금은 그렇지 않고 ctoc_cmd 가 무조건 핸들링 하는데, 겉 보기엔 멀쩡해보이지만, payload_len == 0 인 케이스에도, payload_cb를 설정해주고 있다. 이것을 끄면 될 것 같은데... 딱히 그런 문젠 아니었다 -_-;; 그냥 atoi가 잘못되고 있던 것이었다...; param[2] 에 무조건 atoi를 했는데 그러면 안 된다. 리턴 메시지는 훨씬 파라메터수가 적다.

처리 해주고나니 쪽지 주고 받기와 로그인은 잘 되는군. ㅋㅋ;;
얼레? 채팅도 잘 된다. 다중로그인 시 채팅은 아닌데 일단은 잘 된다.

내가 접속중인데 남이 다중접속으로 들어온 경우는 에러가 발생하는군. 처리해보자.

blist: Updating buddy status for xxx@nate.com (NateOn)

자기 자신이 들어온 것을 notify 받는건 꿈에도 생각 못했을 거다. 아무래도, 자기 자신은 친구 목록엔 없겠지 -_-;;;; 그래서 에러가 난 것이다. 다중 로그인은 쪽지가 서버에서 오므로 그냥, 다중로그인 메시지는 안 뜨는걸로 하자?

ntfy_cmd 수정. 내 자신이 로그인 했으면 그냥, 친구 상태 업데동적을 안 하도록 수정하면 될 듯. 예상대로, 안 튕긴다. -_-;;

로그인 매니저로 로그아웃 시킨 때에는 피진이 통째로 로그아웃 된다. 해결하기 현재로서는 귀찮다... 만 뭔가 기능이 동작 하려다가 튕기는걸로 봐선 단순 메모리 에러일듯.

음... 또 문제가 있군. 피진에서 채팅을 시작했을 땐 괜찮은데, 거꾸로 네톤에서 말 걸면 대화가 안 된다. 아무래도 프로토콜 차이가 도지는듯.

(2011-02-15 23:13:35) --> [ Chat ] {ENTR 1 xxx@nate.com|dpc_01204:19747|bwzc 카라%20ㅠㅠ 홍길동 05715F2E71006CEA86 UTF8 P 3.0 1
}
(2011-02-15 23:13:35) <-- [ Chat ] {ENTR 1}
(2011-02-15 23:13:35) --> CTOC 37 yyy@nate.com N 61
INVT xxx@nate.com 120.50.133.109 5004 05715F2E71006CEA86
(2011-02-15 23:13:45) --> [ Chat ] {MESG 2 TYPING 1
}
(2011-02-15 23:13:45) <-- [ Chat ] {280 2}
(2011-02-15 23:13:45) --> RESS 38 
(2011-02-15 23:13:45) --> [ Chat ] {MESG 3 TYPING 0
}
(2011-02-15 23:13:45) <-- [ Chat ] {280 3}
(2011-02-15 23:13:45) <-- RESS 38 120.50.133.108 5004 0468EC0C19006CED54
(2011-02-15 23:13:45) --> [ Chat ] {LOUT
}
(2011-02-15 23:13:45) --> [ Chat ] {ENTR 4 xxx@nate.com|dpc_01204:19747|bwzc 카라%20ㅠㅠ 홍길동 0468EC0C19006CED54 UTF8 P 3.0 1
}
(2011-02-15 23:13:45) <-- [ Chat ] {ENTR 4}
(2011-02-15 23:13:45) --> CTOC 39 yyy@nate.com N 61
INVT xxx@nate.com 120.50.133.108 5004 0468EC0C19006CED54
(2011-02-15 23:13:50) --> [ Chat ] {MESG 5 MSG 굴림%090%09%09헐
}
(2011-02-15 23:13:50) <-- [ Chat ] {280 5}
이거는 네톤쪽 돌아가는 모양

(23:13:50) nateon: C: SB 002: ENTR 1 yyy@nate.com killer 홍길동 0468EC0C19006CED54PING UTF8 P
(23:13:50) nateon: S: SB 002: 270 1 
(23:13:50) nateon: [entr_error] error(270)
(23:13:50) nateon: nateon_error: command ENTR gave error 270
(23:13:50) msg: Error: Unable to call the user yyy@nate.com for reason 3
(23:13:50) nateon: nateon_switchboard_close
dns[13221]: nobody needs me... =(
이쪽은 피진쪽 돌아가는 모양. 아마 ENTR 라고 반응한게 불만이라서 그럴 듯 -_-;;

이거는 제대로 네톤이 보낸 메시지를 수신하는 쪽임.
(2011-02-15 23:20:41) <-- RESS 66 120.50.133.105 5004 035026E52F006A62CB
(2011-02-15 23:20:41) <-- RESS 65 120.50.133.109 5004 04523D886E006CEF68
(2011-02-15 23:20:44) <-- NPRM 0 xxx@nate.com dpc_07803:29770|X0HA 0 %00
(2011-02-15 23:20:53) <-- CTOC 0 xxx@nate.com dpc_07803:29770|X0HA 62
INVT xxx@nate.com 120.50.133.106 5004 0504DDF3C7006A59BA
(2011-02-15 23:20:53) --> [ Chat ] {ENTR 1 yyy@nate.com|dpc_01204:19747|bwzc 카라%20ㅠㅠ 홍길동 0504DDF3C7006A59BA UTF8 P 3.0 1
}
(2011-02-15 23:20:53) <-- [ Chat ] {USER 0 1 1 xxx@nate.com 데헷 홍길동 3.0 1}
(2011-02-15 23:20:53) <-- [ Chat ] {ENTR 1}
(2011-02-15 23:20:53) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_07803:29770|X0HA DPIMG REQUEST%091|0|기본%09DPI00.bmp|10856|0:2147483647:566}
(2011-02-15 23:20:53) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_07803:29770|X0HA AVCHAT2 OBJECT%090}
(2011-02-15 23:20:53) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_07803:29770|X0HA FONT REQDATA%09굴림%09%099%090%090%09}
(2011-02-15 23:20:53) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_07803:29770|X0HA MAIL REQUEST}
(2011-02-15 23:20:57) <-- [ Chat ] {MESG 0 xxx@nate.com TYPING 1}
(2011-02-15 23:20:58) <-- [ Chat ] {MESG 0 xxx@nate.com TYPING 0}
(2011-02-15 23:20:58) <-- [ Chat ] {MESG 0 xxx@nate.com TYPING 1}
(2011-02-15 23:20:58) <-- PING 0
(2011-02-15 23:20:58) --> PING 67 
(2011-02-15 23:20:59) <-- [ Chat ] {MESG 0 xxx@nate.com EMOTICON USECUST%09}
(2011-02-15 23:20:59) <-- [ Chat ] {MESG 0 xxx@nate.com MSG 굴림%090%09%09야%20놀자}
(2011-02-15 23:20:59) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_07803:29770|X0HA DPIMG REQUEST%091|0|기본%09DPI00.bmp|10856|1:2147483647:585}
(2011-02-15 23:21:01) --> [ Chat ] {MESG 2 TYPING 1
}
(2011-02-15 23:21:01) <-- [ Chat ] {MESG 2}
(2011-02-15 23:21:02) --> [ Chat ] {MESG 3 MSG 굴림%090%09%09그려
}
(2011-02-15 23:21:02) --> [ Chat ] {MESG 4 TYPING 0
}
(2011-02-15 23:21:02) <-- [ Chat ] {MESG 3}
(2011-02-15 23:21:02) <-- [ Chat ] {MESG 4}
으음 뭐지 -_-;;

네톤의
putENTRSS
함수에 ENTR 구문을 만드는 법이 적혀있다.

1. CTOC로 INVT 메시지가 딸려옴.
INVT xxx@nate.com 120.50.133.106 5004 0504DDF3C7006A59BA
2. 거기에 보안키가 적혀있으니 그걸 컨닝해서 ENTR 명령도 만들어야 함.
ENTR 1 yyy@nate.com|dpc_01204:19747|bwzc 카라%20ㅠㅠ 홍길동 0504DDF3C7006A59BA UTF8 P 3.0 1

저기 보이는 dpc 머시기는 DP key라고, 로그인 할 때 서버의 LSIN 답신에서 온다 (읔). 결국 보안이 강화되면 저렇게 드럽고 지저분하게 되는건가!! 모든 것에 그냥 뭔가 덕지덕지 붙어서... -_-;;

LSIN부터 처리해야겠군. LSIN에 dpkey를 네톤 세션 변수에 저장하도록 하는 코드를 넣었고 (ticket이란걸 이미 저장하고 있더군), 그리고 세션이 종료되면 ticket버리는 코드와 함께 dpkey도 버리는 코드를 넣었다.

ENTR 1 yyy@nate.com killer 홍길동 0468EC0C19006CED54PING UTF8 P
ENTR 1 yyy@nate.com|dpc_01204:19747|bwzc 카라%20ㅠㅠ 홍길동 0504DDF3C7006A59BA UTF8 P 3.0 1
비교해보면 거의 똑같은데, 내 메일주소에 dpkey가 붙고 이상한 bwzc같은 썸이 하나 더 붙고, 그 뒤는 똑같다가 버전 정보인 3.0 1 이 붙는다. 3.0과 1이 뭔진 나도 모른다. 그냥, 네톤 코드에도 3.0 1이 하드코딩 되어 있다. 아... 체크썸이 아니라 그냥 dpkey에 따라 붙어있다 (그래도 체크섬처럼 보이는데).

ENTR 1 xxx@nate.com|dpc_01002:23614|63Jj 데헷 홍길동 0221D9453E0068717BPING UTF8 P 3.0 1 (피진)
ENTR 1 yyy@nate.com|dpc_01204:19747|bwzc 카라%20ㅠㅠ 홍길동 0504DDF3C7006A59BA UTF8 P 3.0 1 (네톤)
왜 안되지.

(23:57:54) nateon: S: SB 002: 270 1 
(23:57:54) nateon: [entr_error] error(270)
#define NXME_INVALID_SESSION_KEY  "270"
세션키가 안 맞는다니 무슨소리야 OTL

knateon.cpp KNateon::gotINVT
nateondpconnection.cpp NateonDPConnection::parseBuffer
parseBuffer에서 INVT를 보면 emit에 의해, 이벤트를 발생시키고 결국 gotINVT가 수행되는 듯.

여기부터 디벼봐야겠음.
INVT를 처리할 때에는
1. SS(네톤용어)인지 SB(피진용어)인지 요상한 중개 서버에 접속을 해야 하고,
2. 그리고 대화 당사자들간에도 뭔가 하는 이중구조이다 (???)
일까??

ENTR 명령어는 아무리 봐도 제대로 되었다. 아마 switch board에 접속을 이상하게 하는건지도 모르겠다.

채팅방 중개서버(? sb? switch board?)  접속 코드를 네톤 코드에서 컨닝하면
/// connection이 Success되었다고 해 정말 접속이 된것이 아님.
/// KExtendedSocket 의 connectionSuccess() signal을 받아야 정말 접속이 된것임.
요런 마음에 걸리는 말이 적혀있다... 만 Qt3 버그(?) 때문에 적힌 코멘트인듯. (connection 함수에 들어가서 거기 코멘트를 읽어봤다)

trans = nateon_transaction_new(cmdproc,
        "ENTR", "%s|%s %s %s %s UTF8 P 3.0 1",
            purple_account_get_username(account),
            cmdproc->session->dpkey,
            purple_strreplace(user->store_name, " ", "%20"),
            user->friendly_name,
            swboard->auth_key);
명령어는 맞게 만드는데 trans 변수 자체에, user id가 틀렸을 수도 있지... 라고 생각했지만 trans근 그냥 plain text -_-;;

정답. 윈네톤에서 xxx를 콜했음.
(2011-02-16 12:28:53) <-- CTOC 0 xxx@nate.com dpc_10401:22633|jnVm 61
INVT xxx@nate.com 120.50.133.115 5004 03439FB6BA007195F324x24/s
(2011-02-16 12:28:53) --> [ Chat ] {
ENTR 1 yyy@nate.com|dpc_01003:23615|oBMA 데헷 홍길동 03439FB6BA007195F3 UTF8 P 3.0 1
}
auth key가 왜 INVT에 있는것과 다른가 ㅎㄷㄷ 좀 잘라서 쓴 듯. 정확한 네톤의 구현을 컨닝해야겠다... 근데 컨닝해도 특이 사항이 없다. 하지만 피진에서 버그 찾는 데 성공.

(13:21:18) nateon: S: NS 000: INVT xxx@nate.com 120.50.133.101 5004 0502CAD405003B8DD1PING 0
(13:21:18) nateon: C: SB 001: ENTR 1 yyy@nate.com|dpc_01203:19746|JKGk 데헷 홍길동0502CAD405003B8DD1PING UTF8 P 3.0 1

초대의 key가 이상하게 생겨먹었다. PING 0?! 핑이라니! 다음 request를 잘라먹는 것을 엉터리로 해서 벌어진 일인가 싶다. 쪽지 보내기에서 고친 줄 알았는데 아니었군... 쪽지는 그럴듯 했지만 (아마 우연히 작동한건지도 모르겠다) CTOC이 정확하게 잘라지지 않으면서 엉뚱한 게 붙은 것이다. CTOC 구문을 보니 \r\n을 제외한 길이가 주어지므로 헷갈릴 건덕지는 없고 (있고?)... 이 부분을 고치면 해결될 문제로 보인다.

왜 그런고 봤더니, end를 \0로 바꾸는걸 안 해줘서 그런 것 같기도 하고 -_-;;; 그건 아닌게, payload가 있는 경우에 도는 코드에 printf를 넣어 봤더니 출력이 안 되고 있다 -_-;; 추적해보니 ctoc_cmd 에서 잘못하는 거 같음... 어? 잘 하고 있는 거 같음 -_-;;

ctoc_cmd_post
여기서 잘못하고 있나? 그렇다. len이 parameter로 오는데 무시하거든.
근데 ctoc_cmd_post도 작동 안 한다. 헐...

그게, 그냥 \r\n을 찾는 코드를 실행한다. CTOC 주제에...

그게 프로토콜이 바뀐 것 때문이다 -_-;; 으헣. CTOC의 몇번째가 payload인지가 다름.

간단한거였지만 한참 삽질했다. 흐휴. PING인걸 보기 전엔 그럴싸해보였는데. 왜 더 코드가 길지... 이 정도?;; atoi함수의 무서움은, 숫자가 아닌 것을 넣어주면 0이 "조용히" 나온단 것이다.

이제 문제는 왜 튕기냐... 인데. 메시지 수신이 되긴 하는걸 보면 오가는 메시지에 대한 프로토콜은 계속 비슷한 듯 하지만, PACK, PNAK 그런건 좀 차이가 나는듯?

(2011-02-16 14:37:46) <-- CTOC 0 xxx@nate.com dpc_06702:15132|jnVm 60
INVT xxx@nate.com 120.50.133.96 5004 016E6A94A500673221
(2011-02-16 14:37:46) --> [ Chat ] {ENTR 1 yyy@nate.com|dpc_01204:19747|oBMA 데헷 홍길동 016E6A94A500673221 UTF8 P 3.0 1
}
(2011-02-16 14:37:46) <-- [ Chat ] {USER 0 1 1 xxx@nate.com 카라%20ㅠㅠ 홍길동 3.0 1}
(2011-02-16 14:37:46) <-- [ Chat ] {ENTR 1}
(2011-02-16 14:37:46) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_06702:15132|jnVm DPIMG REQUEST%091|0|기본%09DPI00.bmp|10856|26:2147483647:614}
(2011-02-16 14:37:46) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_06702:15132|jnVm AVCHAT2 OBJECT%090}
(2011-02-16 14:37:46) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_06702:15132|jnVm FONT REQDATA%09굴림%09%099%090%090%09}
(2011-02-16 14:37:46) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_06702:15132|jnVm MAIL REQUEST}
(2011-02-16 14:37:47) <-- [ Chat ] {MESG 0 xxx@nate.com TYPING 1}
(2011-02-16 14:37:49) <-- [ Chat ] {MESG 0 xxx@nate.com EMOTICON USECUST%091}
(2011-02-16 14:37:49) <-- [ Chat ] {MESG 0 xxx@nate.com MSG 굴림%090%09%09데스라포%20발사!}
(2011-02-16 14:37:49) <-- [ Chat ] {WHSP 0 xxx@nate.com|dpc_06702:15132|jnVm DPIMG REQUEST%091|0|기본%09DPI00.bmp|10856|27:2147483647:623}
(2011-02-16 14:37:50) <-- PING 0
(2011-02-16 14:37:50) --> PING 13 
(2011-02-16 14:37:53) --> [ Chat ] {MESG 2 TYPING 1
}
(2011-02-16 14:37:53) <-- [ Chat ] {MESG 2}
(2011-02-16 14:37:53) --> [ Chat ] {MESG 3 TYPING 0
}
(2011-02-16 14:37:53) <-- [ Chat ] {MESG 3}
(2011-02-16 14:37:54) --> [ Chat ] {MESG 4 TYPING 1
}
(2011-02-16 14:37:54) <-- [ Chat ] {MESG 4}
(2011-02-16 14:37:57) --> [ Chat ] {MESG 5 TYPING 0
}
(2011-02-16 14:37:57) <-- [ Chat ] {MESG 5}
(2011-02-16 14:38:00) --> PONG 0
(2011-02-16 14:38:00) <-- PONG 0
(2011-02-16 14:38:01) --> [ Chat ] {MESG 6 TYPING 1
}
(2011-02-16 14:38:01) <-- [ Chat ] {MESG 6}
(2011-02-16 14:38:02) --> [ Chat ] {MESG 7 MSG 굴림%09255%09%09헣
}
(2011-02-16 14:38:02) --> [ Chat ] {MESG 8 TYPING 0
}
(2011-02-16 14:38:02) <-- [ Chat ] {MESG 7}
(2011-02-16 14:38:02) <-- [ Chat ] {MESG 8}
(2011-02-16 14:38:10) <-- PING 0
(2011-02-16 14:38:10) --> PING 14 
(2011-02-16 14:38:20) <-- PING 0
(2011-02-16 14:38:20) --> PING 15 

이게 모범 답안인데 내 것은 어떻게 동작하나. 음... 괜히 내 클라이언트가 쓸데없이 CTOC명령을 만들어 내는 것 같다? 그것보다 그냥 세그폴트인거 같음 -_-;; 멀쩡한 세션에서 RESS는 왜 콜하지?;;

왠지 알아냈다. 내가 디버그로 놓은 printf가 문제를 일으키는 것이었다 -_-;;

gdb의
thread apply all bt
이 명령어를 쓰면 모든 thread의 stack을 볼 수 있으니 잘 알아두자. printf 넣어서 주먹구구로 하는 것 보다 낫겠지.

메모와 채팅은 잘 되는 듯 하다. 상태변경도 상당히 잘 되고... 이제 원래 하던걸 할 수 있겠군. 상대방이 타이핑 친다는거 인식도 아직 안 된다.

흐음. To be continued.