📄 slp-sa.cc
字号:
#include "slp/slp-sa.h"// SLPsa OTcl linkage classstatic class SLPsaClass : public TclClass { public: SLPsaClass() : TclClass("Application/SLPsa") {} TclObject* create(int, const char*const*) { return (new SLPsa); }} class_slp_sa;void urlExpireTimer::expire(Event *){ s_->remove_service(n_);}// Constructor (also initialize instances of timers)SLPsa::SLPsa() : running_(0){ bind("pktsize_",&pktsize_); number_of_scopes_ = 0; url_head = NULL;}// OTcl command interpreterint SLPsa::command(int argc, const char*const* argv){ Tcl& tcl = Tcl::instance(); if (argc == 3) { if (strcmp(argv[1], "attach-agent") == 0) { agent_ = (Agent*) TclObject::lookup(argv[2]);#ifdef DEBUGSA printf("new server agent=%d\n",agent_); #endif if (agent_ == 0) { tcl.resultf("no such agent %s", argv[2]); return(TCL_ERROR); } // Make sure the underlying agent support MM if(agent_->supportSLP()) { agent_->enableSLP(); } else { tcl.resultf("agent \"%s\" does not support SLP Application", argv[2]); return(TCL_ERROR); } agent_->attachApp(this); return(TCL_OK); } else if (strcmp(argv[1],"add-scope") == 0) { add_scope(argv[2]); return(TCL_OK); } else if (strcmp(argv[1],"remove-scope") == 0) { remove_scope(argv[2]); return(TCL_OK); } } else if (argc == 5) { if (strcmp(argv[1],"add-service") == 0) { add_service(argv[2], atoi(argv[3]), atoi(argv[4])); return(TCL_OK); } } return (Application::command(argc, argv));}void SLPsa::init(){ //add_scope("DEFAULT");}void SLPsa::add_scope(const char* newscope) { char *scope=small_string(newscope); for (int i=0; i<number_of_scopes_; i++) { if (strcmp(local_scopes_[i],scope)==0) { //already in list return; } } if (number_of_scopes_==SLP_MAX_SCOPE) { printf("Can't add anymore scopes, MAX=%d scopes per SA\n",SLP_MAX_SCOPE); return; } local_scopes_[number_of_scopes_]=scope; #ifdef DEBUGSA printf("SA:Added %s(%d), total=%d Scope \n",local_scopes_[number_of_scopes_], strlen(newscope), number_of_scopes_+1);#endif number_of_scopes_++; return;}void SLPsa::remove_scope(const char *removescope) { int i,j; char *scope = small_string(removescope); for (i=0; i<number_of_scopes_; i++) { if (strcmp(local_scopes_[i],scope)==0) break; } number_of_scopes_--; for (j=i; j<number_of_scopes_; j++) { local_scopes_[j]=strdup(local_scopes_[j+1]); }}void SLPsa::add_service(const char* newservice, int timeout, int lifetime) { /*adding new node*/ URLnode *c; c = new URLnode(this, (double)timeout); (c->data).lifetime=lifetime; (c->data).url=strdup(newservice); (c->data).url_length=strlen(newservice); (c->data).auth_no=0; c->next = url_head; url_head = c; #ifdef DEBUGSA printf("SA:Added %s %d\n",(url_head->data).url, (url_head->data).auth_no);#endif}void SLPsa::remove_service(URLnode *removeservice_url) { URLnode *p=NULL, *c=url_head; while ((c!=NULL) && (c != removeservice_url)) { p=c; c=c->next; } if (c==NULL) return; if (p==NULL) url_head = c->next; else p->next = c->next; delete c;}void SLPsa::start(){ init(); running_ = 1; if (number_of_scopes_==0) add_scope("DEFAULT");}void SLPsa::stop(){ running_ = 0;}// Send application data packetvoid SLPsa::send_srvrply_pkt(u_int16_t url_count, const char *service_type, u_int16_t xid, ns_addr_t dest){ #ifdef BCAST dest.addr_=dest.addr_+MULTICAST_ADDR+1; #endif hdr_slp_srvrply srvrply_buf; if (running_) { // the below info is passed to UDPslp agent, which will write it // to SLP SRVRPLY header after packet creation. srvrply_buf.version = SLP_VERSION; srvrply_buf.function_id = SLPTYPE_SRVRPLY; srvrply_buf.flags=0; srvrply_buf.next_ext_offset=0; srvrply_buf.xid = xid; srvrply_buf.language_tag_length=strlen(SLP_LANGUAGE); srvrply_buf.language_tag=SLP_LANGUAGE; srvrply_buf.error_code=0; //first assume no urls, to get size so far srvrply_buf.url_entry_count=0; int size_so_far = srvrply_buf.size(); //now assume packet is big enough to include all urls srvrply_buf.url_entry_count=url_count; //adjust the url_entry_count if packet not big enough, and return max possible string of urls srvrply_buf.url=get_urls(srvrply_buf.url_entry_count, service_type, size_so_far); srvrply_buf.length=srvrply_buf.size(); agent_->sendto(srvrply_buf.length, (char*) &srvrply_buf, dest); // send to UDP #ifdef DEBUGSA printf("n%d: SA sending service reply (xid=%d) to %x:%d\n",agent_->addr(), xid, dest.addr_,dest.port_); printf("reply urls(%d) ptr: %d %s\n",srvrply_buf.url_entry_count, srvrply_buf.url,((hdr_slp_url *) srvrply_buf.url)->url); #endif }}// Send saadvert packetvoid SLPsa::send_saadvert_pkt(u_int16_t xid, ns_addr_t dest){ hdr_slp_saadvert saadvert_buf; char url_[30] = "service:service-agent://"; char urla_[5]; sprintf(urla_, "%d", agent_->addr()); strcat (url_,urla_); char * scopes = get_local_scopes(); if (running_) { // the below info is passed to UDPslp agent, which will write it // to SLP SAADVERT header after packet creation. saadvert_buf.version = SLP_VERSION; saadvert_buf.function_id = SLPTYPE_SAADVERT; saadvert_buf.flags=0; saadvert_buf.next_ext_offset=0; saadvert_buf.xid = xid; saadvert_buf.language_tag_length=strlen(SLP_LANGUAGE); saadvert_buf.language_tag=SLP_LANGUAGE; saadvert_buf.length_url=strlen(url_); saadvert_buf.url=strdup(url_); saadvert_buf.length_scope_list=strlen(scopes); saadvert_buf.string_scope_list=scopes; saadvert_buf.length_attr_list=0; saadvert_buf.auth_no=0; saadvert_buf.length=saadvert_buf.size(); agent_->sendto(saadvert_buf.length, (char*) &saadvert_buf, dest); // send to UDP #ifdef DEBUGSA printf("n%d: SA sending service advertisment (xid=%d) to %x:%d\n",agent_->addr(), xid, dest.addr_,dest.port_); printf("url: %s\n",saadvert_buf.url); #endif }}// Receive message from underlying agentvoid SLPsa::recv_slpmsg(ns_addr_t src, int nbytes, const char *msg){ u_int16_t no_urls; bool scopeexists; bool noprexists;#ifdef DEBUG printf("n%d: SA receiving message from %x:%d\n",agent_->addr(), src.addr_, src.port_);#endif if(msg) { hdr_slp* slp_buf = (hdr_slp*) msg; // If received packet is a service request packet if (slp_buf->function_id == SLPTYPE_SRVRQST) { hdr_slp_srvrqst* slp_srvrqst_buf = (hdr_slp_srvrqst*) msg; scopeexists=checkscope(slp_srvrqst_buf->string_scope_list, slp_srvrqst_buf->length_scope_list); noprexists=checkprlist(slp_srvrqst_buf->string_prlist, slp_srvrqst_buf->length_prlist); if (strcmp(slp_srvrqst_buf->string_service_type,"service:service-agent")==0) { if ((!scopeexists) && (slp_srvrqst_buf->length_scope_list!=0)) return; if (!noprexists) return; send_saadvert_pkt(slp_srvrqst_buf->xid, src); } else { if (!scopeexists) return; if (!noprexists) return; if ((no_urls=checkservice(slp_srvrqst_buf->string_service_type)) < 1) return; send_srvrply_pkt(no_urls, slp_srvrqst_buf->string_service_type, slp_srvrqst_buf->xid, src); } } }} bool SLPsa::checkscope(const char* scope_list, u_int16_t length_scope){ if (length_scope==0) return false; char *delimiters = ","; char *token; char scope[length_scope]; strcpy(scope,scope_list); token=strtok(scope, delimiters); while (token!=NULL) {#ifdef DEBUGSA printf("Token is %s\n",token);;#endif for(int i=0; i<number_of_scopes_; i++) { if (strcmp(local_scopes_[i],token)==0) return true; } token=strtok(NULL, delimiters); } return false;} static bool match(const char *url, const char *service){ int position; char *token; char *temp1; char *temp2; temp1=strdup(url); token=strstr(temp1,"://"); position = token -temp1; temp2=strndup(temp1,position); delete temp1; if (strstr(temp2,service) != NULL) { delete temp2; return true; } else { delete temp2; return false; } }u_int16_t SLPsa::checkservice(const char* service_type){ URLnode *s = url_head; u_int16_t no_urls=0; while (s!=NULL) { #ifdef DEBUGSA printf("SLPsa: comparing %s with %s service\n",(s->data).url, service_type);; #endif if (match((s->data).url, service_type) == true) no_urls++; s=s->next; } return no_urls; } bool SLPsa::checkprlist(const char* pr_list, u_int16_t length_pr_list){ if (length_pr_list==0) return true; char *delimiters = ","; char *token; char prlist[length_pr_list]; strcpy(prlist,pr_list); token=strtok(prlist, delimiters); while (token!=NULL) {#ifdef DEBUGSA printf("prToken is %s, comparing with n%d\n",token,agent_->addr());#endif if (agent_->addr()==atoi(token)) return false; token=strtok(NULL, delimiters); } return true;} char * SLPsa::get_urls (u_int16_t &no_urls, const char *serv_type, int size_so_far){ URLnode *c = url_head; char *buff; //maximum memory that needs to be allocated buff = (char *)malloc(sizeof(hdr_slp_url)*no_urls); int i=0; int size=size_so_far; u_int16_t new_no_urls=0; while (c!=NULL) { if (match((c->data).url,serv_type)==true) { //if next url will make pkt overflow, then don't add anymore if ( (size += (c->data).size()) > pktsize_) break; memcpy(buff+i,&(c->data), sizeof(hdr_slp_url)); i+=sizeof(hdr_slp_url); new_no_urls++; } c=c->next; } //adjust no_urls no_urls = new_no_urls; //shrink memory already allocated if necessary (i.e. if new_no_urls < original no_urls) buff = (char *) realloc(buff, sizeof(hdr_slp_url)*no_urls); #ifdef DEBUGSA i=0; for (int j=0; j<no_urls; j++) { printf("okay %d %d %s\n",((hdr_slp_url *)(buff+i))->lifetime,((hdr_slp_url *)(buff+i))->auth_no, ((hdr_slp_url *)(buff+i))->url); i+=sizeof(hdr_slp_url); } #endif return buff; } char * SLPsa::get_local_scopes() const{ char buf[21]; char str[SLP_MAX_SCOPE*20]=""; for (int i=0; i<number_of_scopes_; i++) { if (i==0) { sprintf(buf,"%s",local_scopes_[i]); strcat(str,buf); } else { sprintf(buf,",%s",local_scopes_[i]); strcat(str,buf); } } return strdup(str);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -