From: leslie Date: Mon, 7 Sep 2009 12:20:28 +0000 (+0800) Subject: network API rework (involves all cardclients) X-Git-Tag: upstream/620~182 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=54dd1663d9a9d601c93ff701da9b6de1066cef1b;p=sasc-ng.git network API rework (involves all cardclients) --- diff --git a/network.c b/network.c index 1a319f7..124d815 100644 --- a/network.c +++ b/network.c @@ -34,6 +34,10 @@ #include "misc.h" #include "log-core.h" +#define DEFAULT_CONNECT_TIMEOUT 20*1000 // ms +#define DEFAULT_READWRITE_TIMEOUT 3*1000 // ms +#define DEFAULT_IDLE_TIMEOUT 120*1000 // ms + const char *netscript=0; int netTimeout=60*1000; // timeout for shutting down dialup-network @@ -144,11 +148,11 @@ int cNetWatcher::RunCommand(const char *cmd, const char *state) // -- cNetSocket ------------------------------------------------------------------ -cNetSocket::cNetSocket(int ConnectTimeout, int ReadWriteTimeout, int IdleTimeout, bool Udp) +cNetSocket::cNetSocket(void) { - hostname=0; sd=-1; connected=netup=quietlog=false; - udp=Udp; conTimeout=ConnectTimeout; rwTimeout=ReadWriteTimeout; - idleTimeout=IdleTimeout*1000; + hostname=0; sd=-1; udp=connected=netup=quietlog=false; + conTimeout=DEFAULT_CONNECT_TIMEOUT; rwTimeout=DEFAULT_READWRITE_TIMEOUT; + idleTimeout=DEFAULT_IDLE_TIMEOUT; } cNetSocket::~cNetSocket() @@ -236,7 +240,6 @@ bool cNetSocket::Connect(const char *Hostname, int Port, int timeout) return false; } - bool cNetSocket::Bind(const char *Hostname, int Port) { nw.Block(); @@ -270,7 +273,7 @@ void cNetSocket::Disconnect(void) nw.Block(); cMutexLock lock(this); if(sd>=0) { close(sd); sd=-1; } - connected=false; + quietlog=connected=false; if(netup) { nw.Down(this); netup=false; } nw.Unblock(); } @@ -284,29 +287,36 @@ void cNetSocket::Flush(void) } } -// len>0 : read available bytes, up to len -// len<0 : block read len bytes or fail +// len>0 : block read len bytes or fail +// len<0 : read available bytes up to len int cNetSocket::Read(unsigned char *data, int len, int timeout) { cMutexLock lock(this); if(timeout<0) timeout=rwTimeout; - bool fullread=false; - if(len<0) { len=-len; fullread=true; } + bool blockmode=true; + if(len<0) { len=-len; blockmode=false; } int cnt=0, r; + cTimeMs tim; do { - r=Select(true,timeout); + r=timeout; + if(blockmode) { r-=tim.Elapsed(); if(r<10) r=10; } + r=Select(true,r); if(r>0) { - r=LOOP_EINTR(read(sd,data,len)); + r=LOOP_EINTR(read(sd,data+cnt,len-cnt)); if(r<0) PRINTF(L_GEN_ERROR,"socket: read failed: %s",strerror(errno)); else if(r>0) cnt+=r; + else { + PRINTF(L_GEN_ERROR,"socket: EOF on read"); + errno=ECONNRESET; + } } - } while(r>0 && cnt0 && cnt0) { + if((!blockmode && cnt>0) || cnt>=len) { HEXDUMP(L_CORE_NETDATA,data,cnt,"network read"); return cnt; } - return r; + return -1; } int cNetSocket::Write(const unsigned char *data, int len, int timeout) @@ -314,8 +324,10 @@ int cNetSocket::Write(const unsigned char *data, int len, int timeout) cMutexLock lock(this); if(timeout<0) timeout=rwTimeout; int cnt=0, r; + cTimeMs tim; do { - r=Select(false,timeout); + r=timeout-tim.Elapsed(); if(r<10) r=10; + r=Select(false,r); if(r>0) { r=LOOP_EINTR(write(sd,data+cnt,len-cnt)); if(r<0) PRINTF(L_GEN_ERROR,"socket: write failed: %s",strerror(errno)); @@ -323,11 +335,11 @@ int cNetSocket::Write(const unsigned char *data, int len, int timeout) } } while(r>0 && cnt0) { + if(cnt>=len) { HEXDUMP(L_CORE_NETDATA,data,cnt,"network write"); return cnt; } - return r; + return -1; } int cNetSocket::SendTo(const char *Host, int Port, const unsigned char *data, int len, int timeout) @@ -337,21 +349,23 @@ int cNetSocket::SendTo(const char *Host, int Port, const unsigned char *data, in int cnt=0, r=-1; struct sockaddr_in saddr; if(GetAddr(&saddr,Host,Port)) { + cTimeMs tim; do { - r=Select(false,timeout); + r=timeout-tim.Elapsed(); if(r<10) r=10; + r=Select(false,r); if(r>0) { - r=LOOP_EINTR(sendto(sd,data,len,0,(struct sockaddr *)&saddr,sizeof(saddr))); + r=LOOP_EINTR(sendto(sd,data+cnt,len-cnt,0,(struct sockaddr *)&saddr,sizeof(saddr))); if(r<0) PRINTF(L_GEN_ERROR,"socket: sendto %d.%d.%d.%d:%d failed: %s",(saddr.sin_addr.s_addr>> 0)&0xff,(saddr.sin_addr.s_addr>> 8)&0xff,(saddr.sin_addr.s_addr>>16)&0xff,(saddr.sin_addr.s_addr>>24)&0xff,Port,strerror(errno)); else if(r>0) cnt+=r; } } while(r>0 && cnt0) { + if(cnt>=len) { HEXDUMP(L_CORE_NETDATA,data,cnt,"network sendto %d.%d.%d.%d:%d",(saddr.sin_addr.s_addr>> 0)&0xff,(saddr.sin_addr.s_addr>> 8)&0xff,(saddr.sin_addr.s_addr>>16)&0xff,(saddr.sin_addr.s_addr>>24)&0xff,Port); return cnt; } - return r; + return -1; } int cNetSocket::Select(bool forRead, int timeout) @@ -360,8 +374,11 @@ int cNetSocket::Select(bool forRead, int timeout) fd_set fds; FD_ZERO(&fds); FD_SET(sd,&fds); struct timeval tv; - if(timeout&MSTIMEOUT) { tv.tv_sec=0; tv.tv_usec=(timeout&~MSTIMEOUT)*1000; } - else { tv.tv_sec=timeout; tv.tv_usec=0; } + + if(timeout>0 && timeout<60) + PRINTF(L_GEN_DEBUG,"socket: internal: small timeout value %d",timeout); + + tv.tv_sec=timeout/1000; tv.tv_usec=(timeout%1000)*1000; int r=LOOP_EINTR(select(sd+1,forRead ? &fds:0,forRead ? 0:&fds,0,&tv)); if(r>0) return 1; else if(r<0) { @@ -369,7 +386,8 @@ int cNetSocket::Select(bool forRead, int timeout) return -1; } else { - if(timeout>0 && !quietlog) PRINTF(L_CORE_NET,"socket: select timed out (%d %s)",timeout&~MSTIMEOUT,(timeout&MSTIMEOUT)?"ms":"secs"); + if(timeout>0 && !quietlog) PRINTF(L_CORE_NET,"socket: select timed out (%d ms)",timeout); + errno=ETIMEDOUT; return 0; } } diff --git a/network.h b/network.h index c19d5c7..d93b89f 100644 --- a/network.h +++ b/network.h @@ -26,12 +26,6 @@ // ---------------------------------------------------------------- -#define DEFAULT_CONNECT_TIMEOUT 20 -#define DEFAULT_READWRITE_TIMEOUT 3 -#define DEFAULT_IDLE_TIMEOUT 120 - -#define MSTIMEOUT 0x800000 - extern const char *netscript; extern int netTimeout; @@ -53,7 +47,7 @@ private: bool GetAddr(struct sockaddr_in *saddr, const char *Hostname, int Port); int GetSocket(bool Udp); public: - cNetSocket(int ConnectTimeout, int ReadWriteTimeout, int IdleTimeout, bool Udp=false); + cNetSocket(void); ~cNetSocket(); bool Connect(const char *Hostname, int Port, int timeout=-1); bool Bind(const char *Hostname, int Port); @@ -64,6 +58,10 @@ public: void Flush(void); bool Connected(void) { return connected; } void SetQuietLog(bool ql) { quietlog=ql; } + void SetConnectTimeout(int to) { conTimeout=to; } + void SetRWTimeout(int to) { rwTimeout=to; } + void SetIdleTimeout(int to) { idleTimeout=to; } + void SetUDP(bool u) { udp=u; } }; #endif //___NETWORK_H diff --git a/systems/cardclient/aroureos.c b/systems/cardclient/aroureos.c index ad08173..60da8a5 100644 --- a/systems/cardclient/aroureos.c +++ b/systems/cardclient/aroureos.c @@ -21,15 +21,12 @@ #include #include "cc.h" -#include "network.h" #include "parse.h" // -- cCardClientAroureos ------------------------------------------------------ class cCardClientAroureos : public cCardClient, protected cIdSet { private: - cNetSocket so; - // bool ParseCardConfig(const char *config, int *num); protected: virtual bool Login(void); @@ -44,8 +41,9 @@ static cCardClientLinkReg __aroureos("Aroureos"); cCardClientAroureos::cCardClientAroureos(const char *Name) :cCardClient(Name) -,so(DEFAULT_CONNECT_TIMEOUT,5,DEFAULT_IDLE_TIMEOUT) -{} +{ + so.SetRWTimeout(5*1000); +} bool cCardClientAroureos::ParseCardConfig(const char *config, int *num) { @@ -93,7 +91,7 @@ bool cCardClientAroureos::ProcessEMM(int caSys, const unsigned char *source) unsigned char *buff=AUTOMEM(length+8); memcpy(buff,"EMM",3); memcpy(&buff[3],source,length); - SendMsg(&so,buff,length+3); + SendMsg(buff,length+3); msEMM.Cache(id,true,0); } return true; @@ -112,12 +110,10 @@ bool cCardClientAroureos::ProcessECM(const cEcmInfo *ecm, const unsigned char *s memcpy(buff,"ECM",3); memcpy(&buff[3],source,len); - if(!SendMsg(&so,buff,96)) return false; - int n=RecvMsg(&so,buff,sizeof(buff)); - if(n>0) { + if(!SendMsg(buff,96)) return false; + if(RecvMsg(buff,16)>0 && !CheckNull(buff,16)) { memcpy(cw,buff,16); - for(n=0; n<16; n++) if(cw[n]) break; - if(n<16) return true; + return true; } } return false; diff --git a/systems/cardclient/camd.c b/systems/cardclient/camd.c index 0216451..22f3c6d 100644 --- a/systems/cardclient/camd.c +++ b/systems/cardclient/camd.c @@ -22,7 +22,6 @@ #include #include "cc.h" -#include "network.h" #include "crypto.h" #include "misc.h" #include "parse.h" @@ -42,15 +41,15 @@ private: cCondVar sleepCond; cTimeMs time; protected: - cNetSocket so; bool emmProcessing; char username[11], password[11]; + int emmReqLen; // virtual bool Login(void); bool ParseKeyConfig(const char *config, int *num); bool ParseUserConfig(const char *config, int *num); - virtual bool SendMsg(cNetSocket *so, const unsigned char *data, int len); - virtual int RecvMsg(cNetSocket *so, unsigned char *data, int len, int to=-1); + virtual bool SendMsg(const unsigned char *data, int len); + virtual int RecvMsg(unsigned char *data, int len, int to=-1); virtual void HandleEMMRequest(const unsigned char *buff, int len) {} virtual bool CanHandleEMM(int SysId) { return false; } public: @@ -62,10 +61,11 @@ public: cCardClientCommon::cCardClientCommon(const char *Name, bool ConReply, bool LogReply, bool DoAES, int MinMsgLen) :cCardClient(Name) -,so(DEFAULT_CONNECT_TIMEOUT,CCTIMEOUT/1000,DEFAULT_IDLE_TIMEOUT) { conReply=ConReply; logReply=LogReply; doAES=DoAES; minMsgLen=MinMsgLen; emmProcessing=exclusive=false; + so.SetRWTimeout(CCTIMEOUT); + emmReqLen=-64; } bool cCardClientCommon::ParseUserConfig(const char *config, int *num) @@ -98,7 +98,7 @@ bool cCardClientCommon::ParseKeyConfig(const char *config, int *num) return true; } -bool cCardClientCommon::SendMsg(cNetSocket *so, const unsigned char *data, int len) +bool cCardClientCommon::SendMsg(const unsigned char *data, int len) { unsigned char *buff2=AUTOMEM(minMsgLen); if(len0) { data=buff; len=l; } - return cCardClient::SendMsg(so,data,len); + return cCardClient::SendMsg(data,len); } -int cCardClientCommon::RecvMsg(cNetSocket *so, unsigned char *data, int len, int to) +int cCardClientCommon::RecvMsg(unsigned char *data, int len, int to) { - int n=cCardClient::RecvMsg(so,data,len,to); + int n=cCardClient::RecvMsg(data,len,to); if(n>0) { if(n&15) PRINTF(L_CC_CAMD,"AES crypted message length not a multiple of 16"); Decrypt(data,n); @@ -144,7 +144,7 @@ bool cCardClientCommon::Login(void) unsigned char buff[128]; if(conReply) { - if(RecvMsg(&so,buff,sizeof(buff))!=16) { + if(RecvMsg(buff,16)<0) { PRINTF(L_CC_CAMD,"bad connect reply"); return false; } @@ -158,11 +158,11 @@ bool cCardClientCommon::Login(void) int vers_len=strlen(CCVERSION)+1; memcpy(buff+1+user_len+pass_len+1,CCVERSION,vers_len); PRINTF(L_CC_CAMD,"login user='%s' password=hidden version=%s",username,CCVERSION); - if(!SendMsg(&so,buff,32)) return false; + if(!SendMsg(buff,32)) return false; if(emmAllowed && logReply) { PRINTF(L_CC_CAMD,"waiting for login reply ..."); - int r=RecvMsg(&so,buff,sizeof(buff)); + int r=RecvMsg(buff,emmReqLen); if(r>0) HandleEMMRequest(buff,r); } PRINTF(L_CC_LOGIN,"%s: login done",name); @@ -185,7 +185,7 @@ bool cCardClientCommon::ProcessEMM(int caSys, const unsigned char *source) buff[6]=((cCardIrdeto *)card)->hexBase; memcpy(&buff[7],source,length); //PRINTF(L_CC_CAMD,"%s: sending EMM for caid 0x%04X",name,caSys); - SendMsg(&so,buff,length+7); + SendMsg(buff,length+7); msEMM.Cache(id,true,0); } return true; @@ -203,18 +203,18 @@ bool cCardClientCommon::ProcessECM(const cEcmInfo *ecm, const unsigned char *sou const int length=SCT_LEN(source); unsigned char *buff=AUTOMEM(length+32); int n; - while((n=RecvMsg(&so,buff,16,0))>0) HandleEMMRequest(buff,n); + while((n=RecvMsg(buff,-16,0))>0) HandleEMMRequest(buff,n); buff[0]=0x02; buff[1]=(ecm->caId>>8); buff[2]=(ecm->caId&0xFF); memset(&buff[3],0,4); memcpy(&buff[7],source,length); - if(SendMsg(&so,buff,length+7)) { + if(SendMsg(buff,length+7)) { exclusive=true; time.Set(CCTIMEOUT); do { sleepCond.TimedWait(*this,50); - while((n=RecvMsg(&so,buff,32,0))>0) { + while((n=RecvMsg(buff,-32,0))>0) { if(n>=21 && buff[0]==2) { if(!CheckNull(buff+5,16)) { if(!res) { @@ -243,6 +243,8 @@ bool cCardClientCommon::ProcessECM(const cEcmInfo *ecm, const unsigned char *sou // -- cCardClientCamd33 -------------------------------------------------------- +#define EMMREQLEN33 13 + class cCardClientCamd33 : public cCardClientCommon { private: int CAID; @@ -262,6 +264,7 @@ cCardClientCamd33::cCardClientCamd33(const char *Name) { CAID=0; memset(lastEmmReq,0,sizeof(lastEmmReq)); + emmReqLen=EMMREQLEN33; } bool cCardClientCamd33::CanHandle(unsigned short SysId) @@ -276,7 +279,7 @@ bool cCardClientCamd33::CanHandleEMM(int SysId) void cCardClientCamd33::HandleEMMRequest(const unsigned char *buff, int len) { - if(len>=13 && buff[0]==0 && !CheckNull(buff,len) && memcmp(buff,lastEmmReq,13)) { + if(len>=emmReqLen && buff[0]==0 && !CheckNull(buff,len) && memcmp(buff,lastEmmReq,emmReqLen)) { emmProcessing=false; int c=buff[1]*256+buff[2]; if(c!=CAID) CaidsChanged(); @@ -356,8 +359,8 @@ bool cCardClientBuffy::Login(void) unsigned char buff[128]; memset(buff,0,sizeof(buff)); buff[0]=0x0A; - if(!SendMsg(&so,buff,32)) return false; - int n=RecvMsg(&so,buff,sizeof(buff)); + if(!SendMsg(buff,32)) return false; + int n=RecvMsg(buff,-sizeof(buff)); if(n<0) return false; for(int i=1; i __camd35("Camd35"); cCardClientCamd35::cCardClientCamd35(const char *Name) :cCardClient(Name) -,so(DEFAULT_CONNECT_TIMEOUT,CCTIMEOUT/1000,DEFAULT_IDLE_TIMEOUT,true) { emmProcessing=exclusive=emmCmd06=false; pinid=0; numCaids=0; lastEmmReq=0; memset(Dx,0,sizeof(Dx)); + so.SetRWTimeout(CCTIMEOUT); + so.SetUDP(true); } bool cCardClientCamd35::ParseUserConfig(const char *config, int *num) @@ -476,29 +479,37 @@ bool cCardClientCamd35::SendBlock(struct CmdBlock *cb, int datalen) HEXDUMP(L_CC_CAMDEXTR,cb,datalen+UCSIZE(cb),"send:"); const int l=Encrypt((unsigned char *)cb+UCSIZE(cb),datalen,buff+UCSIZE(cb)); if(l<=0) return false; - return cCardClient::SendMsg(&so,buff,l+UCSIZE(cb)); + return cCardClient::SendMsg(buff,l+UCSIZE(cb)); } int cCardClientCamd35::RecvBlock(struct CmdBlock *cb, int maxlen, int to) { - int n=cCardClient::RecvMsg(&so,(unsigned char *)cb,maxlen,to); - if(n<=0) return n; - if((unsigned int)n>=CBSIZE(cb)+UCSIZE(cb)) { - if(cb->ucrc==ucrc) { - Decrypt((unsigned char *)cb+UCSIZE(cb),n-UCSIZE(cb)); - if((unsigned int)nudp_header.len+CBSIZE(cb)+UCSIZE(cb)) - PRINTF(L_CC_CAMD35,"packet length doesn't match data length"); - else if(cb->udp_header.crc!=bswap_32(crc32_le(0,&cb->data[0],cb->udp_header.len))) - PRINTF(L_CC_CAMD35,"data crc failed"); - else { - HEXDUMP(L_CC_CAMDEXTR,cb,n,"recv:"); - return n; - } - } - else PRINTF(L_CC_CAMD35,"wrong ucrc: got %08x, want %08x",cb->ucrc,ucrc); + unsigned char *m=(unsigned char *)cb; + if(cCardClient::RecvMsg(m,16+UCSIZE(cb),to)<0) { + PRINTF(L_CC_CAMD35,"short packet received"); + return -1; + } + Decrypt(m+UCSIZE(cb),16); + int n=cb->udp_header.len+HDSIZE(cb); + if(n>maxlen) { + PRINTF(L_CC_CAMD35,"received buffer overflow"); + return -1; } - else PRINTF(L_CC_CAMD35,"short packet received"); - return -1; + if(cCardClient::RecvMsg(m+16+UCSIZE(cb),n-(16+UCSIZE(cb)),200)<0) { + PRINTF(L_CC_CAMD35,"short packet received(2)"); + return -1; + } + Decrypt(m+16+UCSIZE(cb),n-(16+UCSIZE(cb))); + if(cb->ucrc!=ucrc) { + PRINTF(L_CC_CAMD35,"wrong ucrc: got %08x, want %08x",cb->ucrc,ucrc); + return -1; + } + if(cb->udp_header.crc!=bswap_32(crc32_le(0,&cb->data[0],cb->udp_header.len))) { + PRINTF(L_CC_CAMD35,"data crc failed"); + return -1; + } + HEXDUMP(L_CC_CAMDEXTR,cb,n,"recv:"); + return n; } bool cCardClientCamd35::Init(const char *config) diff --git a/systems/cardclient/cc.c b/systems/cardclient/cc.c index d9fcafe..e0b9a0c 100644 --- a/systems/cardclient/cc.c +++ b/systems/cardclient/cc.c @@ -26,7 +26,6 @@ #include "system.h" #include "cc.h" #include "sc.h" -#include "network.h" #include "misc.h" #include "opts.h" #include "log-core.h" @@ -102,25 +101,24 @@ bool cCardClient::CanHandle(unsigned short SysId) return false; } -bool cCardClient::SendMsg(cNetSocket *so, const unsigned char *data, int len) +bool cCardClient::SendMsg(const unsigned char *data, int len) { - if(!so->Connected() && !Login()) return false; - if(so->Write(data,len)<0) { + if(!so.Connected() && !Login()) return false; + if(so.Write(data,len)<0) { PRINTF(L_CC_CORE,"send error. reconnecting...");; - so->Disconnect(); + so.Disconnect(); return false; } return true; } -int cCardClient::RecvMsg(cNetSocket *so, unsigned char *data, int len, int to) +int cCardClient::RecvMsg(unsigned char *data, int len, int to) { - if(!so->Connected() && !Login()) return -1; - int n=so->Read(data,len,to); - if(n<0 || (n==0 && to!=0)) { + if(!so.Connected() && !Login()) return -1; + int n=so.Read(data,len,to); + if(n<0) { PRINTF(L_CC_CORE,"recv error. reconnecting...");; - so->Disconnect(); - return -1; + so.Disconnect(); } return n; } diff --git a/systems/cardclient/cc.h b/systems/cardclient/cc.h index a8f5eef..06b1372 100644 --- a/systems/cardclient/cc.h +++ b/systems/cardclient/cc.h @@ -22,6 +22,7 @@ #include #include "system.h" +#include "network.h" #include "misc.h" #include "log.h" @@ -58,6 +59,7 @@ class cSystemCardClient; class cCardClient : public cStructItem, protected cMutex { friend class cSystemCardClient; protected: + cNetSocket so; const char *name; char hostname[64]; int port; @@ -66,8 +68,8 @@ protected: cMsgCache msECM, msEMM; // bool ParseStdConfig(const char *config, int *num=0); - virtual bool SendMsg(cNetSocket *so, const unsigned char *data, int len); - virtual int RecvMsg(cNetSocket *so, unsigned char *data, int len, int to=-1); + virtual bool SendMsg(const unsigned char *data, int len); + virtual int RecvMsg(unsigned char *data, int len, int to=-1); virtual bool Login(void) { return false; } bool Immediate(void); void CaidsChanged(void); diff --git a/systems/cardclient/cccam.c b/systems/cardclient/cccam.c index 920392a..f6a0fba 100644 --- a/systems/cardclient/cccam.c +++ b/systems/cardclient/cccam.c @@ -27,7 +27,6 @@ #include #include "cc.h" -#include "network.h" #define LIST_ONLY 0x03 /* CA application should clear the list when an 'ONLY' CAPMT object is received, and start working with the object */ @@ -164,7 +163,6 @@ bool cCCcamCard::GetCw(unsigned char *Cw, int timeout) class cCardClientCCcam : public cCardClient, private cThread { private: - cNetSocket so; cCCcamCard card[4]; int pmtversion; int failedcw; @@ -184,9 +182,10 @@ static cCardClientLinkReg __ncd("cccam"); cCardClientCCcam::cCardClientCCcam(const char *Name) :cCardClient(Name) ,cThread("CCcam listener") -,so(DEFAULT_CONNECT_TIMEOUT,2,3600,true) { pmtversion=0; socketpath=0; + so.SetRWTimeout(2*1000); + so.SetUDP(true); } cCardClientCCcam::~cCardClientCCcam() @@ -212,8 +211,8 @@ bool cCardClientCCcam::Login(void) { cMutexLock lock(this); so.Disconnect(); - so.SetQuietLog(true); if(!so.Bind("127.0.0.1",port)) return false; + so.SetQuietLog(true); PRINTF(L_CC_CCCAM,"Bound to port %d, starting UDP listener",port); Start(); return true; @@ -311,12 +310,10 @@ void cCardClientCCcam::Action(void) { unsigned char cw[18]; while(Running()) { - int r=so.Read(cw,sizeof(cw)); - if(r==sizeof(cw)) { + if(so.Read(cw,sizeof(cw)>0)) { LDUMP(L_CC_CCCAM,cw+2,16,"got: %02x%02x ",cw[0],cw[1]); if(cw[1]==0x0f && cw[0]<4) card[cw[0]].NewCw(cw+2); } - else if(r>0) PRINTF(L_CC_CCCAM,"unexpected read length r=%d",r); } } diff --git a/systems/cardclient/cccam2.c b/systems/cardclient/cccam2.c index 9258888..cbbd120 100644 --- a/systems/cardclient/cccam2.c +++ b/systems/cardclient/cccam2.c @@ -27,7 +27,6 @@ #include #include "cc.h" -#include "network.h" #include "helper.h" #include "version.h" @@ -433,7 +432,6 @@ class cCardClientCCcam2 : public cCardClient , private cThread { private: cCCcamCrypt encr, decr; cShares shares; - cNetSocket so; unsigned char nodeid[8]; int shareid; char username[21], password[64]; @@ -462,9 +460,9 @@ static cCardClientLinkReg __ncd("cccam2"); cCardClientCCcam2::cCardClientCCcam2(const char *Name) :cCardClient(Name) ,cThread("CCcam2 listener") -,so(DEFAULT_CONNECT_TIMEOUT,2,600) { shareid=0; newcw=login=false; + so.SetRWTimeout(10*1000); } cCardClientCCcam2::~cCardClientCCcam2() @@ -605,13 +603,13 @@ bool cCardClientCCcam2::Login(void) unsigned char buffer[512]; int len; - if((len=so.Read(buffer,sizeof(buffer),10))<=0) { + if((len=so.Read(buffer,16))<0) { PRINTF(L_CC_CCCAM2,"no welcome from server"); Logout(); return false; } LDUMP(L_CC_CCCAM2DT,buffer,len,"welcome answer:"); - if(len!=16 || !cCCcamCrypt::CheckConnectChecksum(buffer,len)) { + if(!cCCcamCrypt::CheckConnectChecksum(buffer,len)) { PRINTF(L_CC_CCCAM2,"bad welcome from server"); Logout(); return false; @@ -628,7 +626,7 @@ bool cCardClientCCcam2::Login(void) LDUMP(L_CC_CCCAM2DT,buff2,20,"welcome response:"); encr.Encrypt(buff2,buffer,20); - if(so.Write(buffer,20)!=20) { + if(so.Write(buffer,20)<0) { PRINTF(L_CC_CCCAM2,"failed to send welcome response"); Logout(); return false; @@ -638,7 +636,7 @@ bool cCardClientCCcam2::Login(void) strcpy((char *)buff2,username); LDUMP(L_CC_CCCAM2DT,buff2,20,"send username:"); encr.Encrypt(buff2,buffer,20); - if(so.Write(buffer,20)!=20) { + if(so.Write(buffer,20)<0) { PRINTF(L_CC_CCCAM2,"failed to send username"); Logout(); return false; @@ -646,13 +644,13 @@ bool cCardClientCCcam2::Login(void) encr.Encrypt((unsigned char *)password,buffer,strlen(password)); encr.Encrypt((unsigned char *)cccamstr,buffer,6); - if(so.Write(buffer,6)!=6) { + if(so.Write(buffer,6)<0) { PRINTF(L_CC_CCCAM2,"failed to send password hash"); Logout(); return false; } - if((len=so.Read(buffer,sizeof(buffer),6))<=0) { + if((len=so.Read(buffer,20))<0) { PRINTF(L_CC_CCCAM2,"no login answer from server"); Logout(); return false; @@ -660,7 +658,7 @@ bool cCardClientCCcam2::Login(void) decr.Decrypt(buffer,buffer,len); LDUMP(L_CC_CCCAM2DT,buffer,len,"login answer:"); - if(len<20 || strcmp(cccamstr,(char *)buffer)!=0) { + if(strcmp(cccamstr,(char *)buffer)!=0) { PRINTF(L_CC_CCCAM2,"login failed"); Logout(); return false; @@ -677,7 +675,7 @@ bool cCardClientCCcam2::Login(void) memcpy(clt.nodeid,nodeid,8); LDUMP(L_CC_CCCAM2DT,&clt,sizeof(clt),"send clientinfo:"); encr.Encrypt((unsigned char*)&clt,buffer,sizeof(clt)); - if(so.Write(buffer,sizeof(clt))!=sizeof(clt)) { + if(so.Write(buffer,sizeof(clt))<0) { PRINTF(L_CC_CCCAM2,"failed to send clientinfo"); Logout(); return false; @@ -726,7 +724,7 @@ bool cCardClientCCcam2::ProcessECM(const cEcmInfo *ecm, const unsigned char *dat PRINTF(L_CC_CCCAM2EX,"now try shareid %08x",shareid); LDUMP(L_CC_CCCAM2DT,req,ecm_len,"send ecm:"); encr.Encrypt((unsigned char *)req,netbuff,ecm_len); - if(so.Write(netbuff,ecm_len)!=ecm_len) { + if(so.Write(netbuff,ecm_len)<0) { PRINTF(L_CC_CCCAM2,"failed so send ecm request"); Logout(); break; @@ -764,7 +762,7 @@ void cCardClientCCcam2::Action(void) int cnt=0; while(Running() && so.Connected()) { unsigned char recvbuff[1024]; - int len=so.Read(recvbuff+cnt,sizeof(recvbuff)-cnt,MSTIMEOUT|200); + int len=so.Read(recvbuff+cnt,-(sizeof(recvbuff)-cnt),200); if(len>0) { decr.Decrypt(recvbuff+cnt,recvbuff+cnt,len); HEXDUMP(L_CC_CCCAM2DT,recvbuff+cnt,len,"net read: len=%d cnt=%d",len,cnt+len); diff --git a/systems/cardclient/gbox.c b/systems/cardclient/gbox.c index 7be1a47..4e81637 100644 --- a/systems/cardclient/gbox.c +++ b/systems/cardclient/gbox.c @@ -28,15 +28,12 @@ #include #include "cc.h" -#include "network.h" #include "parse.h" // -- cGboxClient ----------------------------------------------------------- class cCardClientGbox : public cCardClient { private: - cNetSocket so; - // int GetMsg(int cmd, unsigned char *buff, int len); protected: virtual bool Login(void); @@ -50,8 +47,10 @@ static cCardClientLinkReg __ncd("gbox"); cCardClientGbox::cCardClientGbox(const char *Name) :cCardClient(Name) -,so(DEFAULT_CONNECT_TIMEOUT,2,DEFAULT_IDLE_TIMEOUT,true) -{} +{ + so.SetRWTimeout(2*1000); + so.SetUDP(true); +} bool cCardClientGbox::Init(const char *config) { @@ -72,11 +71,8 @@ int cCardClientGbox::GetMsg(int cmd, unsigned char *buff, int len) { int n; do { - n=so.Read(buff,len); - if(n<=0) { - if(n==0) PRINTF(L_CC_GBOX,"timeout on GetMsg."); - break; - } + n=so.Read(buff,-len); + if(n<0) break; } while(buff[0]!=cmd); return n; } @@ -115,12 +111,12 @@ bool cCardClientGbox::ProcessECM(const cEcmInfo *ecm, const unsigned char *data, SetSctLen(&buff[1],sizeof(pmt)-4+n+4); buff[2]=(buff[2]&0x0F)|0xB0; - if(so.SendTo("127.0.0.1",8004,buff,sizeof(pmt)+n+4)<(int)sizeof(pmt)) { + if(so.SendTo("127.0.0.1",8004,buff,sizeof(pmt)+n+4)<0) { PRINTF(L_CC_GBOX,"failed to send PMT data. GBOX running?"); return false; } - if((n=GetMsg(0x8a,buff,sizeof(buff)))<=0) { + if((n=GetMsg(0x8a,buff,sizeof(buff)))<0) { PRINTF(L_CC_GBOX,"failed to get ECM port. GBOX running?"); return false; } @@ -149,12 +145,12 @@ bool cCardClientGbox::ProcessECM(const cEcmInfo *ecm, const unsigned char *data, buff[3]=n; memcpy(&buff[4],data,n); n+=4; - if(so.SendTo("127.0.0.1",8005+pidnum,buff,n) #include "cc.h" -#include "network.h" #include "misc.h" #include "parse.h" @@ -168,7 +167,6 @@ struct CustomData { class cCardClientNewCamd : public cCardClient, private cTripleDes, private cIdSet { private: - cNetSocket so; unsigned char configKey[14]; unsigned short netMsgId; int caId, protoVers, cdLen; @@ -200,12 +198,12 @@ static cCardClientLinkReg __ncd("Newcamd"); cCardClientNewCamd::cCardClientNewCamd(const char *Name) :cCardClient(Name) -,so(DEFAULT_CONNECT_TIMEOUT,20,DEFAULT_IDLE_TIMEOUT) { memset(username,0,sizeof(username)); memset(password,0,sizeof(password)); InitVars(); InitProtoVers(525); + so.SetRWTimeout(20*1000); } void cCardClientNewCamd::InitVars(void) @@ -287,30 +285,28 @@ bool cCardClientNewCamd::SendMessage(const unsigned char *data, int len, bool Us len+=sizeof(DES_cblock); netbuf[0]=(len-2)>>8; netbuf[1]=(len-2)&0xff; - return cCardClient::SendMsg(&so,netbuf,len); + return cCardClient::SendMsg(netbuf,len); } int cCardClientNewCamd::ReceiveMessage(unsigned char *data, bool UseMsgId, struct CustomData *cd, comm_type_t commType) { unsigned char netbuf[CWS_NETMSGSIZE]; - int len=cCardClient::RecvMsg(&so,netbuf,2); - if(len!=2) { - if(len>0) PRINTF(L_CC_NEWCAMD,"bad length %d != 2 on message length read",len); + if(cCardClient::RecvMsg(netbuf,2)<0) { + PRINTF(L_CC_NEWCAMD,"failed to read message length"); return 0; } - const int mlen=WORD(netbuf,0,0xFFFF); + int mlen=WORD(netbuf,0,0xFFFF); if(mlen>CWS_NETMSGSIZE-2) { PRINTF(L_CC_NEWCAMD,"receive message buffer overflow"); return 0; } - len=cCardClient::RecvMsg(&so,netbuf+2,mlen); - if(len!=mlen) { - PRINTF(L_CC_NEWCAMD,"bad length %d != %d on message read",len,mlen); + if(cCardClient::RecvMsg(netbuf+2,mlen,200)<0) { + PRINTF(L_CC_NEWCAMD,"failed to read message"); return 0; } - len+=2; - cTripleDes::Decrypt(netbuf,len); len-=sizeof(DES_cblock); - if(XorSum(netbuf+2, len-2)) { + mlen+=2; + cTripleDes::Decrypt(netbuf,mlen); mlen-=sizeof(DES_cblock); + if(XorSum(netbuf+2,mlen-2)) { PRINTF(L_CC_NEWCAMD,"checksum error"); return 0; } @@ -340,7 +336,7 @@ int cCardClientNewCamd::ReceiveMessage(unsigned char *data, bool UseMsgId, struc bool cCardClientNewCamd::CmdSend(net_msg_type_t cmd, comm_type_t commType) { unsigned char buffer[3]; - buffer[0] = cmd; buffer[1] = buffer[2] = 0; + buffer[0]=cmd; buffer[1]=buffer[2]=0; return SendMessage(buffer,sizeof(buffer),false,0,commType); } @@ -377,7 +373,7 @@ bool cCardClientNewCamd::Login(void) InitVars(); unsigned char randData[14]; - if(so.Read(randData,sizeof(randData))!=14) { + if(so.Read(randData,sizeof(randData))<0) { PRINTF(L_CC_NEWCAMD,"no connect answer from %s:%d",hostname,port); so.Disconnect(); return false; diff --git a/systems/cardclient/radegast.c b/systems/cardclient/radegast.c index a4907a7..e41db88 100644 --- a/systems/cardclient/radegast.c +++ b/systems/cardclient/radegast.c @@ -22,7 +22,6 @@ #include "cc.h" #include "parse.h" -#include "network.h" #include "version.h" // -- cCardClientRadegast ------------------------------------------------------ @@ -31,7 +30,6 @@ class cCardClientRadegast : public cCardClient, private cIdSet { private: - cNetSocket so; bool emmProcessing; int caids[MAXCAIDS], numCaids; // @@ -61,9 +59,9 @@ static cCardClientLinkReg __rdg("Radegast"); cCardClientRadegast::cCardClientRadegast(const char *Name) :cCardClient(Name) -,so(DEFAULT_CONNECT_TIMEOUT,7,DEFAULT_IDLE_TIMEOUT) { InitVars(); + so.SetRWTimeout(7*1000); } void cCardClientRadegast::InitVars(void) @@ -148,24 +146,26 @@ void cCardClientRadegast::AddNano(unsigned char *buff, int nano, int len, const bool cCardClientRadegast::Send(const unsigned char *buff) { - return SendMsg(&so,buff,GetMsgLength(buff)); + return SendMsg(buff,GetMsgLength(buff)); } int cCardClientRadegast::Recv(unsigned char *buff, int len) { - int n=RecvMsg(&so,buff,len); - if(n<1) return n; - int k=GetNanoStart(buff); - if(n0 && buff[0]==0x91) { + if(!Send(buff) || Recv(buff,sizeof(buff))<0) return false; + if(buff[0]==0x91) { PRINTF(L_CC_RDGD,"got server hello, assuming V4 mode"); StartMsg(buff,0x94); // RDGD_MSG_CLIENT_CAP_REQ; + int n; if(!Send(buff) || (n=Recv(buff,sizeof(buff)))<0) return false; - if(n>0 && buff[0]==0x95) { + if(buff[0]==0x95) { LBSTARTF(L_CC_LOGIN); LBPUT("radegast: got caps"); int caid; @@ -248,7 +248,7 @@ bool cCardClientRadegast::ProcessECM(const cEcmInfo *ecm, const unsigned char *s if(!CheckLength(buff,len)) return false; AddNano(buff,3,len,source); // ECM_NANO_PACKET - if(!Send(buff) || (len=Recv(buff,sizeof(buff)))<=0) return false; + if(!Send(buff) || (len=Recv(buff,sizeof(buff)))<0) return false; if(buff[0]==2) { for(int l=GetNanoStart(buff); l=9 && + if(so.Write(buff,l+5)>0 && + so.Read(buff,9)>0 && buff[0]==0x7A && buff[1]==0xA7 && buff[2]==0x00 && buff[3]==0x04 && buff[8]==0xff && ((buff[4]<<8)|buff[5])==AUX_PROTOCOL_VERSION) return true; PRINTF(L_SYS_MAP,"auxsrv: login write failed"); @@ -87,22 +83,25 @@ int cAuxSrv::Map(int map, unsigned char *data, int len, int outlen) buff[4]=map; memcpy(&buff[5],data,len); buff[len+5]=0xFF; - if(so.Write(buff,len+6)==len+6) { - if((len=so.Read(buff,sizeof(buff)))>0) { + if(so.Write(buff,len+6)>0) { + if(so.Read(buff,5)>0) { if(buff[0]==0x7A && buff[1]==0xA7) { - if(buff[4]==0x00) { - int cycles=(buff[5]<<16)|(buff[6]<<8)|buff[7]; - int l=buff[2]*256+buff[3]; - if(len>=l+5 && l==outlen+4) { - if(buff[l+4]==0xFF) { - memcpy(data,buff+8,outlen); - return cycles; + int l=buff[2]*256+buff[3]; + if(so.Read(buff+5,l,200)>0) { + if(buff[4]==0x00) { + int cycles=(buff[5]<<16)|(buff[6]<<8)|buff[7]; + if(l==outlen+4) { + if(buff[l+4]==0xFF) { + memcpy(data,buff+8,outlen); + return cycles; + } + else PRINTF(L_SYS_MAP,"auxsrv: bad footer in map%02x response",map); } - else PRINTF(L_SYS_MAP,"auxsrv: bad footer in map%02x response",map); + else PRINTF(L_SYS_MAP,"auxsrv: bad length in map%02x response (got=%d want=%d)",map,l-4,outlen); } - else PRINTF(L_SYS_MAP,"auxsrv: bad length in map%02x response (got=%d,%d want=%d,%d)",map,l-4,len,outlen,l+8); + else PRINTF(L_SYS_MAP,"auxsrv: map%02x not successfull (unsupported?)",map); } - else PRINTF(L_SYS_MAP,"auxsrv: map%02x not successfull (unsupported?)",map); + else PRINTF(L_SYS_MAP,"auxsrv: map%02x read failed (2)",map); } else PRINTF(L_SYS_MAP,"auxsrv: bad response to map%02x",map); } diff --git a/version.h b/version.h index 0afd27b..9296973 100644 --- a/version.h +++ b/version.h @@ -25,7 +25,7 @@ extern const char *ScVersion; // SC API version number for loading shared libraries -#define SCAPIVERS 27 +#define SCAPIVERS 28 #ifndef STATICBUILD #define SCAPIVERSTAG() int ScLibApiVersion=SCAPIVERS #else