Esempio n. 1
0
int main()
{
  constexpr int i = 42;
  SA(noexcept(*f(&i)));
  SA(noexcept(f(&i)));
}
Esempio n. 2
0
/*
 * \fn hip_dht_resolve_hi()
 *
 * \param hi	pointer to host identity whose name, LSI, or HIT can be used
 *              for lookups, and the HIT and address may be updated
 * \param retry if TRUE, we'll spawn a new thread an retry multiple times
 *              without blocking
 *
 * \return	returns -1 if there is a problem, 0 otherwise
 *
 * \brief Given a Host Identity, perform a DHT lookup using its HIT and store
 * any resulting address in the hi_node. If the HIT is missing, perform a HIT
 * lookup in the DHT using the name and/or LSI.
 */
int hip_dht_resolve_hi(hi_node *hi, int retry)
{
  int err;
  struct sockaddr_storage ss_addr;
  struct sockaddr *addr = (struct sockaddr*) &ss_addr;
  sockaddr_list *list;
  char hit_str[INET6_ADDRSTRLEN];
#ifndef __WIN32__
  pthread_attr_t attr;
  pthread_t thr;
#endif
  if (hip_dht_select_server(addr) < 0)
    {
      return(0);           /* prevents unneccessary thread creation */

    }
  /* When retry is turned on, a separate thread will be forked that
   * will perform the DHT lookup(s), retry a certain number of times,
   * and exit */
  if (retry == TRUE)
    {
#ifdef __WIN32__
      _beginthread(hip_dht_resolve_hi_thread, 0, (void *)hi);
#else
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      pthread_create(&thr, &attr, hip_dht_resolve_hi_thread, hi);
#endif
      return(0);
      /* We have been recursively called from a thread */
    }
  else if (retry == 2)
    {
      retry = TRUE;           /* used for calls below... */
    }

  /*
   * First locate the HIT using the peer's name if this HIT is missing.
   */
  if (hits_equal(hi->hit, zero_hit))
    {
      if (hi->name_len == 0)
        {
          log_(NORM,
               "HIT and name not present, unable to perform"
               " DHT lookup.\n");
          return(-1);
        }
      log_(NORM,
           "HIT not present for peer %s, performing DHT lookup "
           "using the name '%s'.\n",
           logaddr(SA(&hi->lsi)),
           hi->name);
      if ((err = hip_dht_lookup_hit_by_name(hi->name, &hi->hit,
                                            retry)) < 0)
        {
          /* no HIT from name, so we cannot do address lookup */
          log_(WARN, "Unable to find HIT for %s in the DHT.\n",
               logaddr(SA(&hi->lsi)));
          return(err);
        }
      else
        {
          hit_to_str(hit_str, hi->hit);
          log_(NORM, "Discovered HIT for peer %s using the DHT: "
               "%s\n", hi->name, hit_str);
        }
    }

  /*
   * Look up current IP address using HIT as key
   */
  memset(addr, 0, sizeof(struct sockaddr_storage));
  addr->sa_family = AF_INET;
  if ((err = hip_dht_lookup_address(&hi->hit, addr, retry)) < 0)
    {
      return(err);
    }

  /* add address to list, checking if first item is empty */
  pthread_mutex_lock(&hi->addrs_mutex);
  if ((hi->addrs.status == DELETED) || !VALID_FAM(&hi->addrs.addr))
    {
      memcpy(&hi->addrs.addr, addr, SALEN(addr));
      hi->addrs.if_index = 0;
      hi->addrs.lifetime = 0;
      hi->addrs.status = UNVERIFIED;
      hi->addrs.nonce = 0;
      gettimeofday(&hi->addrs.creation_time, NULL);
    }
  else
    {
      list = &hi->addrs;
      add_address_to_list(&list, addr, 0);
    }
  pthread_mutex_unlock(&hi->addrs_mutex);

  return(0);
}
Esempio n. 3
0
// AVS
// completelly rewrited to support new conceptions
int TMapLoader::Load(const char * filename, const char * szActiveEmul) {
	char buf[256];
	int bufLen;
	
	ifstream inpfile(filename);
	KeyTrans.DeleteAllDefs();
	Charmap.init();
	
	// it is an array for store [...] ... [end ...] parts from file
	stringArray SA(0,0,sizeof(string));
	int AllOk = 0;
	
	while ( inpfile ) {
		
		getline(inpfile, buf, 255);
		bufLen = strlen(buf);
		if ( !bufLen ) continue;
		
		if ( buf[0] == '[' && buf[bufLen-1] == ']' ) {
			// is a part splitter [...]
			string temps(buf);
			
			if (!normalizeSplitter(temps)) {
				printm(0, FALSE, MSG_KEYUNEXPLINE, temps.c_str());
				AllOk = 0;
				break;
			};
			// if a comment
			if ( stricmp(temps.c_str(),"[comment]") == 0 ) {
#ifdef KEYDEBUG
				printit(temps.c_str());
#endif
				if ( !getLongComment(inpfile, buf, sizeof(buf)) ) {
					printm(0, FALSE, MSG_KEYUNEXPEOF);
					break;
				};
#ifdef KEYDEBUG
				printit("\r          \r");
#endif
				continue;
			};
			
			
			string back = temps;
			// prepare line for make it as [end ...]
			// and check it
			if ( strnicmp(back.c_str(), "[global]", 8) == 0 ) {} // do nothing
			else if ( strnicmp(back.c_str(), "[keymap", 7) == 0 ) {
				// DJGPP also uses erase rather than remove (Paul Brannan 6/23/98)
#ifndef __BORLANDC__
				back.erase(7);
#else
				back.remove(7);
#endif
				back += "]";
			}
			else if ( strnicmp(back.c_str(), "[charmap", 8) == 0 ) {
				// Paul Brannan 6/23/98
#ifndef __BORLANDC__
				back.erase(8);
#else
				back.remove(8);
#endif
				back += "]";
			}
			else if ( strnicmp(back.c_str(), "[config", 7) == 0 ) {
				// Paul Brannan 6/23/98
#ifndef __BORLANDC__
				back.erase(7);
#else
				back.remove(7);
#endif
				back += "]";
			}
			else {
				//        cerr << "Unexpected token " << back << endl;
				printm(0, FALSE, MSG_KEYUNEXPTOK, back.c_str());
				break;
			};
			
			back.insert(1,"END "); // now it looks like [END ...]
#ifdef KEYDEBUG
			printit(temps.c_str());
#endif
			
			int ok = 0;
			// fetch it to temps
			while ( 1 ) {
				getline(inpfile, buf, sizeof(buf));
				bufLen = strlen(buf);
				if ( !bufLen ) break;
				if ( buf[0] == '[' && buf[bufLen-1] == ']' ) {
					string t(buf);
					if ( !normalizeSplitter(t) ) break;
					
					if ( stricmp(t.c_str(),back.c_str()) == 0 ) {
						ok = 1;
						break;
					};
					
					// AVS 31.12.97 fix [comment] block inside another block
					if ( stricmp(t.c_str(),"[comment]") == 0 &&
						getLongComment(inpfile, buf, sizeof(buf)) ) continue;
					
					break;
				};
				temps += "\n";
				temps += buf;
			};
			if ( !ok ) {
				//         cerr << "Unexpected end of file or token" << endl;
				printm(0, FALSE, MSG_KEYUNEXP);
				AllOk = 0;
				break;
			};
#ifdef KEYDEBUG
			printit("\r                                                                      \r");
#endif
			AllOk = SA.Add(temps);;
			if ( !AllOk ) break;
		} else {
			//       cerr << "Unexpected line '" << buf << "'\n";
			printm(0, FALSE, MSG_KEYUNEXPLINE, buf);
			AllOk = 0;
			break;
		};
	};
	
	inpfile.close();
	
	if ( !AllOk ) return 0;
	
	// now all file are in SA, comments are stripped
	
	int i = LookForPart(SA, "global", "");
	if ( i == INT_MAX ) {
		//     cerr << "No [GLOBAL] definition!" << endl;
		printm(0, FALSE, MSG_KEYNOGLOBAL);
		return 0;
	};
	if ( !LoadGlobal(SA[i]) ) {
		return 0;
	};
	
	// look for need configuration
	i = LookForPart(SA, "config", szActiveEmul);
	if ( i == INT_MAX ) {
		//     cerr << "No [CONFIG " << szActiveEmul << "]\n";
		printm(0, FALSE, MSG_KEYNOCONFIG, szActiveEmul);
		return 0;
	};
	//  cerr << "use configuration: " << szActiveEmul << endl;
	printm(0, FALSE, MSG_KEYUSECONFIG, szActiveEmul);
	BOOL hadKeys = FALSE;
	
	string config = SA[i];
	// parse it
	while ( config.length() ) {
		buf[0] = 0;
		getline(config,buf,sizeof(buf));
		bufLen = strlen(buf);
		if ( !bufLen || (buf[0] == '[' && buf[bufLen-1] == ']') ) continue;
		if ( strnicmp(buf,"keymap",6) == 0 ) {
			string orig(buf);
			printit("\t"); printit(buf); printit("\n");
			char * mapdef = strtok(buf,":");
			char * switchKey = strtok(NULL,"\n");
			
			if ( !KeyTrans.mapArray.IsEmpty() && switchKey == NULL ) {
				//            cerr << "no switch Key for '" << mapdef
				//                 << "'" << endl;
				printm(0, FALSE, MSG_KEYNOSWKEY, mapdef);
				break;
			};
			if ( KeyTrans.mapArray.IsEmpty() ) {
				if ( switchKey != NULL ) { // create default keymap
					//               cerr << "You cannot define switch key for default keymap -> ignored"
					//                    << endl;
					printm(0, FALSE, MSG_KEYCANNOTDEF);
				};
				TKeyDef empty;
				KeyTrans.mapArray.Add(KeyMap(string(mapdef)));
				KeyTrans.switchMap(empty); // set it as current keymap
				KeyTrans.mainKeyMap = KeyTrans.currentKeyMap;
			}
			else {
				string keydef(switchKey);
				keydef += " !*!*!*"; // just for check
				WORD vk_code;
				DWORD control;
				switchKey = ParseKeyDef(keydef.c_str(),vk_code,control);
				if ( switchKey != NULL ) {
					TKeyDef swi(NULL,control,vk_code);
					if ( KeyTrans.switchMap(swi) > 0 ) {
						//                  cerr << "Duplicate switching key\n";
						printm(0, FALSE, MSG_KEYDUPSWKEY);
						break;
					};
					KeyTrans.mapArray.Add(KeyMap(swi, orig));
					KeyTrans.switchMap(swi); // set it as current keymap
				}
			};
			mapdef+=7; // 'keymap '
			// now load defined keymaps to current
			while ((mapdef != NULL)&&
				(mapdef = strtok(mapdef,TOKEN_DELIMITERS)) != NULL ) {
				i = LookForPart(SA,"keymap",mapdef);
				if ( i == INT_MAX ) {
					//               cerr << "Unknown KEYMAP " << mapdef << endl;
					printm(0, FALSE, MSG_KEYUNKNOWNMAP, mapdef);
				} else {
					mapdef = strtok(NULL,"\n"); // strtok is used in LoadKeyMap
					// so - save pointer!
					hadKeys = LoadKeyMap(SA[i]); // load it
				};
			};
			
		}
		else if ( strnicmp(buf,"charmap",7) == 0 ) {
			printit("\t"); printit(buf); printit("\n");
			char * mapdef = buf + 8;// 'charmap '
			int SuccesLoaded = 0;
			// now load defined charmaps to current
			while ((mapdef != NULL)&&
				(mapdef = strtok(mapdef,TOKEN_DELIMITERS)) != NULL ) {
				i = LookForPart(SA,"charmap",mapdef);
				if ( i == INT_MAX ) {
					//               cerr << "Unknown KEYMAP " << mapdef << endl;
					printm(0, FALSE, MSG_KEYUNKNOWNMAP, mapdef);
				} else {
					mapdef = strtok(NULL,"\n"); // strtok is used in LoadKeyMap
					// so - save pointer!
					if (LoadCharMap(SA[i])) // load it
						SuccesLoaded++;
				};
			};
			if (!SuccesLoaded) {
				//            cerr << "No charmaps loaded\n";
				printm(0, FALSE, MSG_KEYNOCHARMAPS);
				Charmap.init();
			};
			/*         strtok(buf," ");
			
			  char* name = strtok(NULL," ");
			  if ( name == NULL ) {
			  cerr << "No name for CHARMAP" << endl;
			  } else {
			  i = LookForPart(SA,"charmap", name);
			  if ( i == INT_MAX ) {
			  cerr << "Unknown CHARMAP " << name << endl;
			  } else {
			  LoadCharMap(SA[i]);
			  };
			  };
			*/
		}
		else {
			//        cerr << "unexpected token in " << szActiveEmul << endl;
			printm(0, FALSE, MSG_KEYUNEXPTOKIN, szActiveEmul);
		}
	}

	if ( hadKeys) {
		TKeyDef empty;
		KeyTrans.switchMap(empty); // switch to default
		KeyTrans.mainKeyMap = KeyTrans.currentKeyMap; // save it's number
		//     cerr << "There are " << (KeyTrans.mapArray.GetItemsInContainer()) << " maps\n";
		char s[12]; // good enough for a long int (32-bit)
		itoa(KeyTrans.mapArray.GetItemsInContainer(), s, 10);
		printm(0, FALSE, MSG_KEYNUMMAPS, s);
		return 1;
	};
	return 0;
}
Esempio n. 4
0
static void proxy_manage_event (proxy_t *p, uint32_t events)
{
    struct sockaddr_in6 from, to;
    socklen_t slen;
    int rc, opt;

    (void) events;
    ASSERT(!(p->flags & FLAG_LISTED));
    ASSERT(!(events & EPOLLOUT));
    ASSERT(!(events & (EPOLLHUP|EPOLLERR)));
    if (!p->events)
        return;

    tunnel_t *t = tunnel_reserve(p);
retry:
    slen = sizeof(from);
    t->front.sock = accept4(p->sock_front, SA(&from), &slen,
            SOCK_NONBLOCK|SOCK_CLOEXEC);
    if (t->front.sock < 0) {
        if (errno == EINTR)
            goto retry;
        ASSERT (errno == EAGAIN); 
        tunnel_release(t);
        return proxy_register(p);
    }

    // The proxy front socket is maybe still active. Then instead of
    // systematically sending the proxy in ACTIVE, check if the limit
    // has been reached. It it is, re-monitor for only errors.
    if (p->pipes.max == ++(p->pipes.count))
        proxy_pause(p);
    else
        proxy_resume(p);

    // Poll a backend
    void *buf = NULL;
    rc = nn_recv(p->nn_feed, &buf, NN_MSG, NN_DONTWAIT);
    if (rc < 0) {
        // TODO better manage the backend's starvation (e.g. retry)
        return tunnel_abort(t, "backend starvation: (%d) %s",
            nn_errno(), nn_strerror(nn_errno()));
    } else if (rc > 128) {
        nn_freemsg(buf);
        return tunnel_abort(t, "invalid backend: %s", "URL too big");
    } else {
        char *sto = alloca(rc + 1);
        memcpy(sto, buf, rc);
        sto[rc] = 0;
        rc = sockaddr_init(SA(&to), sto);
        nn_freemsg(buf);
        if (!rc)
            return tunnel_abort(t, "invalid backend: %s", "bad URL");
        char sfrom[64];
        sockaddr_dump(SA(&from), sfrom, sizeof(sfrom));
        ACCESS("%s -> %s", sfrom, sto);
    }

    // Connect to the polled backend
    t->back.sock = socket(SAFAM(&to), SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
    if (t->back.sock < 0)
        return tunnel_abort(t, "socket() error: (%d) %s",
                errno, strerror(errno));

    slen = sizeof(struct sockaddr_in6);
    rc = connect(t->back.sock, SA(&to), slen);
    if (0 > rc && errno != EINPROGRESS)
        return tunnel_abort(t, "connect() error: (%d) %s",
                errno, strerror(errno));

    // Tweak the socket options
    opt = PIPE_SIZE/2;
    setsockopt(t->front.sock, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
    setsockopt(t->back.sock,  SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
    opt = PIPE_SIZE;
    setsockopt(t->front.sock, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
    setsockopt(t->back.sock,  SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));

    errno = 0;
    tunnel_register(t);
}
Esempio n. 5
0
			static std::pair<uint32_t,uint32_t> lcs(std::string const & a, std::string const & b)
			{
				/* concatenate a and b into string c */
				std::string c(a.size()+b.size()+2,' ');
				for ( uint64_t i = 0; i < a.size(); ++i )
					c[i] = a[i]+2;
				c[a.size()] = 0;
				for ( uint64_t i = 0; i < b.size(); ++i )
					c[a.size()+1+i] = b[i]+2;
				c[c.size()-1] = 1;
				
				// allocate suffix sorting
				::libmaus::autoarray::AutoArray<int32_t> SA(c.size(),false);
				
				// perform suffix sorting
				typedef ::libmaus::suffixsort::DivSufSort<32,uint8_t *,uint8_t const *,int32_t *,int32_t const *,8> sort_type;
				typedef sort_type::saidx_t saidx_t;
				sort_type::divsufsort(reinterpret_cast<uint8_t const *>(c.c_str()), SA.get(), c.size());

				// compute LCP array
				::libmaus::autoarray::AutoArray<int32_t> LCP = ::libmaus::suffixsort::SkewSuffixSort<uint8_t,int32_t>::lcpByPlcp(
					reinterpret_cast<uint8_t const *>(c.c_str()), c.size(), SA.get());

				// compute psv and nsv arrays for simulating parent operation on suffix tree
				::libmaus::autoarray::AutoArray<int32_t> const prev = ::libmaus::sv::PSV::psv(LCP.get(),LCP.size());
				::libmaus::autoarray::AutoArray<int32_t> const next = ::libmaus::sv::NSV::nsv(LCP.get(),LCP.size());
				
				#if defined(LCS_DEBUG)
				for ( uint64_t i = 0; i < c.size(); ++i )
				{
					std::cerr << i << "\t" << LCP[i] << "\t" << prev[i] << "\t" << next[i] << "\t";
					for ( std::string::const_iterator ita = c.begin()+SA[i]; ita != c.end(); ++ita )
						if ( isalnum(*ita) )
							std::cerr << *ita;
						else
							std::cerr << "<" << static_cast<int>(*ita) << ">" ;
					std::cerr << std::endl;
				}
				
				std::cerr << "---" << std::endl;
				#endif

				int32_t const n = c.size();
				// queue all suffix tree leafs
				std::deque < QNode > Q;
				for ( int32_t i = 0; i < n; ++i )
					Q.push_back ( QNode(i,i,0, (SA[i]< static_cast<int32_t>(a.size()+1)) ? 1:2, 1 ) );

				// construct hash for tree nodes we have seen so far
				typedef ::libmaus::util::unordered_set < QNode , HashQNode >::type hash_type;
				typedef hash_type::iterator hash_iterator_type;
				typedef hash_type::const_iterator hash_const_iterator_type;
				hash_type H(n);
				
				// we simulate a bottom up traversal of the generalised suffix tree for a and b
				while ( Q.size() )
				{
					// get node and compute parent
					QNode const I = Q.front(); Q.pop_front();
					QNode P = parent(I,LCP.get(),prev.get(),next.get(),n);

					// have we seen this node before?
					hash_iterator_type it = H.find(P);

					// no, insert it
					if ( it == H.end() )
					{
						it = H.insert(P).first;
					}
					// yes, update symbol mask and extend visited interval
					else
					{
						it->symmask |= I.symmask;
						it->fill += (I.right-I.left+1);
					}
					
					// if this is not the root and the node is full (we have seen all its children), 
					// then put it in the queue
					if ( P.right-P.left + 1 < n && it->isFull() )
						Q.push_back(P);
				}
				
				// maximum lcp value
				int32_t maxlcp = 0;
				uint32_t maxpos = 0;
				
				// consider all finished nodes
				for ( hash_const_iterator_type it = H.begin(); it != H.end(); ++it )
				{
					#if defined(LCS_DEBUG)
					std::cerr << *it << std::endl;
					#endif
					
					// we need to have nodes from both strings a and b under this
					// node (sym mask has bits for 1 and 2 set) and the lcp value must be 
					// larger than what we already have
					if ( it->symmask == 3 && it->depth > maxlcp )
					{
						maxlcp = it->depth;
						maxpos = SA[it->left];
					}
				}
				
				return std::pair<uint32_t,uint32_t>(maxlcp,maxpos);
			}
Esempio n. 6
0
static caddr_t
apix_do_softint_prolog(struct cpu *cpu, uint_t pil, uint_t oldpil,
    caddr_t stackptr)
{
	kthread_t *t, *volatile it;
	struct machcpu *mcpu = &cpu->cpu_m;
	hrtime_t now;

	UNREFERENCED_1PARAMETER(oldpil);
	ASSERT(pil > mcpu->mcpu_pri && pil > cpu->cpu_base_spl);

	atomic_and_32((uint32_t *)&mcpu->mcpu_softinfo.st_pending, ~(1 << pil));

	mcpu->mcpu_pri = pil;

	now = tsc_read();

	/*
	 * Get set to run interrupt thread.
	 * There should always be an interrupt thread since we
	 * allocate one for each level on the CPU.
	 */
	it = cpu->cpu_intr_thread;
	ASSERT(it != NULL);
	cpu->cpu_intr_thread = it->t_link;

	/* t_intr_start could be zero due to cpu_intr_swtch_enter. */
	t = cpu->cpu_thread;
	if ((t->t_flag & T_INTR_THREAD) && t->t_intr_start != 0) {
		hrtime_t intrtime = now - t->t_intr_start;
		mcpu->intrstat[pil][0] += intrtime;
		cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
		t->t_intr_start = 0;
	}

	/*
	 * Note that the code in kcpc_overflow_intr -relies- on the
	 * ordering of events here - in particular that t->t_lwp of
	 * the interrupt thread is set to the pinned thread *before*
	 * curthread is changed.
	 */
	it->t_lwp = t->t_lwp;
	it->t_state = TS_ONPROC;

	/*
	 * Push interrupted thread onto list from new thread.
	 * Set the new thread as the current one.
	 * Set interrupted thread's T_SP because if it is the idle thread,
	 * resume() may use that stack between threads.
	 */

	ASSERT(SA((uintptr_t)stackptr) == (uintptr_t)stackptr);
	t->t_sp = (uintptr_t)stackptr;

	it->t_intr = t;
	cpu->cpu_thread = it;

	/*
	 * Set bit for this pil in CPU's interrupt active bitmask.
	 */
	ASSERT((cpu->cpu_intr_actv & (1 << pil)) == 0);
	cpu->cpu_intr_actv |= (1 << pil);

	/*
	 * Initialize thread priority level from intr_pri
	 */
	it->t_pil = (uchar_t)pil;
	it->t_pri = (pri_t)pil + intr_pri;
	it->t_intr_start = now;

	return (it->t_stk);
}
int main()
{
 static constexpr int array[2] = {0, 1};
 constexpr int const * last = is_sorted_until(array, array + 2);
 SA(last==array+2);
}
Esempio n. 8
0
static caddr_t
dosoftint_prolog(
	struct cpu *cpu,
	caddr_t stackptr,
	uint32_t st_pending,
	uint_t oldpil)
{
	kthread_t *t, *volatile it;
	struct machcpu *mcpu = &cpu->cpu_m;
	uint_t pil;
	hrtime_t now;

top:
	ASSERT(st_pending == mcpu->mcpu_softinfo.st_pending);

	pil = bsrw_insn((uint16_t)st_pending);
	if (pil <= oldpil || pil <= cpu->cpu_base_spl)
		return (0);

	/*
	 * XX64	Sigh.
	 *
	 * This is a transliteration of the i386 assembler code for
	 * soft interrupts.  One question is "why does this need
	 * to be atomic?"  One possible race is -other- processors
	 * posting soft interrupts to us in set_pending() i.e. the
	 * CPU might get preempted just after the address computation,
	 * but just before the atomic transaction, so another CPU would
	 * actually set the original CPU's st_pending bit.  However,
	 * it looks like it would be simpler to disable preemption there.
	 * Are there other races for which preemption control doesn't work?
	 *
	 * The i386 assembler version -also- checks to see if the bit
	 * being cleared was actually set; if it wasn't, it rechecks
	 * for more.  This seems a bit strange, as the only code that
	 * ever clears the bit is -this- code running with interrupts
	 * disabled on -this- CPU.  This code would probably be cheaper:
	 *
	 * atomic_and_32((uint32_t *)&mcpu->mcpu_softinfo.st_pending,
	 *   ~(1 << pil));
	 *
	 * and t->t_preempt--/++ around set_pending() even cheaper,
	 * but at this point, correctness is critical, so we slavishly
	 * emulate the i386 port.
	 */
	if (atomic_btr32((uint32_t *)
	    &mcpu->mcpu_softinfo.st_pending, pil) == 0) {
		st_pending = mcpu->mcpu_softinfo.st_pending;
		goto top;
	}

	mcpu->mcpu_pri = pil;
	(*setspl)(pil);

	now = tsc_read();

	/*
	 * Get set to run interrupt thread.
	 * There should always be an interrupt thread since we
	 * allocate one for each level on the CPU.
	 */
	it = cpu->cpu_intr_thread;
	cpu->cpu_intr_thread = it->t_link;

	/* t_intr_start could be zero due to cpu_intr_swtch_enter. */
	t = cpu->cpu_thread;
	if ((t->t_flag & T_INTR_THREAD) && t->t_intr_start != 0) {
		hrtime_t intrtime = now - t->t_intr_start;
		mcpu->intrstat[pil][0] += intrtime;
		cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
		t->t_intr_start = 0;
	}

	/*
	 * Note that the code in kcpc_overflow_intr -relies- on the
	 * ordering of events here - in particular that t->t_lwp of
	 * the interrupt thread is set to the pinned thread *before*
	 * curthread is changed.
	 */
	it->t_lwp = t->t_lwp;
	it->t_state = TS_ONPROC;

	/*
	 * Push interrupted thread onto list from new thread.
	 * Set the new thread as the current one.
	 * Set interrupted thread's T_SP because if it is the idle thread,
	 * resume() may use that stack between threads.
	 */

	ASSERT(SA((uintptr_t)stackptr) == (uintptr_t)stackptr);
	t->t_sp = (uintptr_t)stackptr;

	it->t_intr = t;
	cpu->cpu_thread = it;

	/*
	 * Set bit for this pil in CPU's interrupt active bitmask.
	 */
	ASSERT((cpu->cpu_intr_actv & (1 << pil)) == 0);
	cpu->cpu_intr_actv |= (1 << pil);

	/*
	 * Initialize thread priority level from intr_pri
	 */
	it->t_pil = (uchar_t)pil;
	it->t_pri = (pri_t)pil + intr_pri;
	it->t_intr_start = now;

	return (it->t_stk);
}
int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg)
{
	int             sockfd;
	struct sockaddr_in sinlocal;
	struct sockaddr_in sinremote;
	AUTH_HDR       *auth, *recv_auth;
	uint32_t           auth_ipaddr, nas_ipaddr;
	char           *server_name;	/* Name of server to query */
	socklen_t       salen;
	int             result = 0;
	int             total_length;
	int             length;
	int             retry_max;
	size_t			secretlen;
	char            secret[MAX_SECRET_LENGTH + 1];
	unsigned char   vector[AUTH_VECTOR_LEN];
	char            recv_buffer[BUFFER_LEN];
	char            send_buffer[BUFFER_LEN];
	int		retries;
	VALUE_PAIR 	*vp;
	struct pollfd	pfd;
	double		start_time, timeout;

	server_name = data->server;
	if (server_name == NULL || server_name[0] == '\0')
		return ERROR_RC;

	if ((vp = rc_avpair_get(data->send_pairs, PW_SERVICE_TYPE, 0)) && \
	    (vp->lvalue == PW_ADMINISTRATIVE))
	{
		strcpy(secret, MGMT_POLL_SECRET);
		if ((auth_ipaddr = rc_get_ipaddr(server_name)) == 0)
			return ERROR_RC;
	}
	else
	{
		if(data->secret != NULL)
		{
			strncpy(secret, data->secret, MAX_SECRET_LENGTH);
		}
		/*
		else
		{
		*/
		if (rc_find_server (rh, server_name, &auth_ipaddr, secret) != 0)
		{
			rc_log(LOG_ERR, "rc_send_server: unable to find server: %s", server_name);
			return ERROR_RC;
		}
		/*}*/
	}

	DEBUG(LOG_ERR, "DEBUG: rc_send_server: creating socket to: %s", server_name);

	sockfd = socket (AF_INET, SOCK_DGRAM, 0);
	if (sockfd < 0)
	{
		memset (secret, '\0', sizeof (secret));
		rc_log(LOG_ERR, "rc_send_server: socket: %s", strerror(errno));
		return ERROR_RC;
	}

	memset((char *)&sinlocal, '\0', sizeof(sinlocal));
	sinlocal.sin_family = AF_INET;
	sinlocal.sin_addr.s_addr = htonl(rc_own_bind_ipaddress(rh));
	sinlocal.sin_port = htons((unsigned short) 0);
	if (bind(sockfd, SA(&sinlocal), sizeof(sinlocal)) < 0)
	{
		close (sockfd);
		memset (secret, '\0', sizeof (secret));
		rc_log(LOG_ERR, "rc_send_server: bind: %s: %s", server_name, strerror(errno));
		return ERROR_RC;
	}

	retry_max = data->retries;	/* Max. numbers to try for reply */
	retries = 0;			/* Init retry cnt for blocking call */

	memset ((char *)&sinremote, '\0', sizeof(sinremote));
	sinremote.sin_family = AF_INET;
	sinremote.sin_addr.s_addr = htonl (auth_ipaddr);
	sinremote.sin_port = htons ((unsigned short) data->svc_port);

	/*
	 * Fill in NAS-IP-Address (if needed)
	 */
	if (rc_avpair_get(data->send_pairs, PW_NAS_IP_ADDRESS, 0) == NULL) {
		if (sinlocal.sin_addr.s_addr == htonl(INADDR_ANY)) {
			if (rc_get_srcaddr(SA(&sinlocal), SA(&sinremote)) != 0) {
				close (sockfd);
				memset (secret, '\0', sizeof (secret));
				return ERROR_RC;
			}
		}
		nas_ipaddr = ntohl(sinlocal.sin_addr.s_addr);
		rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IP_ADDRESS,
		    &nas_ipaddr, 0, 0);
	}

	/* Build a request */
	auth = (AUTH_HDR *) send_buffer;
	auth->code = data->code;
	auth->id = data->seq_nbr;

	if (data->code == PW_ACCOUNTING_REQUEST)
	{
		total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;

		auth->length = htons ((unsigned short) total_length);

		memset((char *) auth->vector, 0, AUTH_VECTOR_LEN);
		secretlen = strlen (secret);
		memcpy ((char *) auth + total_length, secret, secretlen);
		rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen);
		memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
	}
	else
	{
		rc_random_vector (vector);
		memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);

		total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;

		auth->length = htons ((unsigned short) total_length);
	}

	DEBUG(LOG_ERR, "DEBUG: local %s : 0, remote %s : %u\n", 
		inet_ntoa(sinlocal.sin_addr),
		inet_ntoa(sinremote.sin_addr), data->svc_port);

	for (;;)
	{
		sendto (sockfd, (char *) auth, (unsigned int) total_length, (int) 0,
			SA(&sinremote), sizeof (struct sockaddr_in));

		pfd.fd = sockfd;
		pfd.events = POLLIN;
		pfd.revents = 0;
		start_time = rc_getctime();
		for (timeout = data->timeout; timeout > 0;
		    timeout -= rc_getctime() - start_time) {
			result = poll(&pfd, 1, timeout * 1000);
			if (result != -1 || errno != EINTR)
				break;
		}
		if (result == -1)
		{
			rc_log(LOG_ERR, "rc_send_server: poll: %s", strerror(errno));
			memset (secret, '\0', sizeof (secret));
			close (sockfd);
			return ERROR_RC;
		}
		if (result == 1 && (pfd.revents & POLLIN) != 0)
			break;

		/*
		 * Timed out waiting for response.  Retry "retry_max" times
		 * before giving up.  If retry_max = 0, don't retry at all.
		 */
		if (retries++ >= retry_max)
		{
			rc_log(LOG_ERR,
				"rc_send_server: no reply from RADIUS server %s:%u, %s",
				 rc_ip_hostname (auth_ipaddr), data->svc_port, inet_ntoa(sinremote.sin_addr));
			close (sockfd);
			memset (secret, '\0', sizeof (secret));
			return TIMEOUT_RC;
		}
	}
	salen = sizeof(sinremote);
	length = recvfrom (sockfd, (char *) recv_buffer,
			   (int) sizeof (recv_buffer),
			   (int) 0, SA(&sinremote), &salen);

	if (length <= 0)
	{
		rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: %s", server_name,\
			 data->svc_port, strerror(errno));
		close (sockfd);
		memset (secret, '\0', sizeof (secret));
		return ERROR_RC;
	}

	recv_auth = (AUTH_HDR *)recv_buffer;

	if (length < AUTH_HDR_LEN || length < ntohs(recv_auth->length)) {
		rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: reply is too short",
		    server_name, data->svc_port);
		close(sockfd);
		memset(secret, '\0', sizeof(secret));
		return ERROR_RC;
	}

	result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr);

	length = ntohs(recv_auth->length)  - AUTH_HDR_LEN;
	if (length > 0) {
		data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data,
		    length, 0);
	} else {
		data->receive_pairs = NULL;
	}

	close (sockfd);
	memset (secret, '\0', sizeof (secret));

	if (result != OK_RC) return result;

	*msg = '\0';
	vp = data->receive_pairs;
	while (vp)
	{
		if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0)))
		{
			strcat(msg, vp->strvalue);
			strcat(msg, "\n");
			vp = vp->next;
		}
	}

	if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
		(recv_auth->code == PW_PASSWORD_ACK) ||
		(recv_auth->code == PW_ACCOUNTING_RESPONSE))
	{
		result = OK_RC;
	}
	else if ((recv_auth->code == PW_ACCESS_REJECT) ||
		(recv_auth->code == PW_PASSWORD_REJECT))
	{
		result = REJECT_RC;
	}
	else
	{
		result = BADRESP_RC;
	}

	return result;
}
Esempio n. 10
0
/*
 * Add any lwp-associated context handlers to the lwp at the beginning
 * of the lwp's useful life.
 *
 * All paths which create lwp's invoke lwp_create(); lwp_create()
 * invokes lwp_stk_init() which initializes the stack, sets up
 * lwp_regs, and invokes this routine.
 *
 * All paths which destroy lwp's invoke lwp_exit() to rip the lwp
 * apart and put it on 'lwp_deathrow'; if the lwp is destroyed it
 * ends up in thread_free() which invokes freectx(t, 0) before
 * invoking lwp_stk_fini().  When the lwp is recycled from death
 * row, lwp_stk_fini() is invoked, then thread_free(), and thus
 * freectx(t, 0) as before.
 *
 * In the case of exec, the surviving lwp is thoroughly scrubbed
 * clean; exec invokes freectx(t, 1) to destroy associated contexts.
 * On the way back to the new image, it invokes setregs() which
 * in turn invokes this routine.
 */
void
lwp_installctx(klwp_t *lwp)
{
	kthread_t *t = lwptot(lwp);
	int thisthread = t == curthread;
#ifdef _SYSCALL32_IMPL
	void (*restop)(klwp_t *) = lwp_getdatamodel(lwp) == DATAMODEL_NATIVE ?
	    lwp_segregs_restore : lwp_segregs_restore32;
#else
	void (*restop)(klwp_t *) = lwp_segregs_restore;
#endif

	/*
	 * Install the basic lwp context handlers on each lwp.
	 *
	 * On the amd64 kernel, the context handlers are responsible for
	 * virtualizing %ds, %es, %fs, and %gs to the lwp.  The register
	 * values are only ever changed via sys_rtt when the
	 * pcb->pcb_rupdate == 1.  Only sys_rtt gets to clear the bit.
	 *
	 * On the i386 kernel, the context handlers are responsible for
	 * virtualizing %gs/%fs to the lwp by updating the per-cpu GDTs
	 */
	ASSERT(removectx(t, lwp, lwp_segregs_save, restop,
	    NULL, NULL, NULL, NULL) == 0);
	if (thisthread)
		kpreempt_disable();
	installctx(t, lwp, lwp_segregs_save, restop,
	    NULL, NULL, NULL, NULL);
	if (thisthread) {
		/*
		 * Since we're the right thread, set the values in the GDT
		 */
		restop(lwp);
		kpreempt_enable();
	}

	/*
	 * If we have sysenter/sysexit instructions enabled, we need
	 * to ensure that the hardware mechanism is kept up-to-date with the
	 * lwp's kernel stack pointer across context switches.
	 *
	 * sep_save zeros the sysenter stack pointer msr; sep_restore sets
	 * it to the lwp's kernel stack pointer (kstktop).
	 */
	if (is_x86_feature(x86_featureset, X86FSET_SEP)) {
#if defined(__amd64)
		caddr_t kstktop = (caddr_t)lwp->lwp_regs;
#elif defined(__i386)
		caddr_t kstktop = ((caddr_t)lwp->lwp_regs - MINFRAME) +
		    SA(sizeof (struct regs) + MINFRAME);
#endif
		ASSERT(removectx(t, kstktop,
		    sep_save, sep_restore, NULL, NULL, NULL, NULL) == 0);

		if (thisthread)
			kpreempt_disable();
		installctx(t, kstktop,
		    sep_save, sep_restore, NULL, NULL, NULL, NULL);
		if (thisthread) {
			/*
			 * We're the right thread, so set the stack pointer
			 * for the first sysenter instruction to use
			 */
			sep_restore(kstktop);
			kpreempt_enable();
		}
	}

	if (PROC_IS_BRANDED(ttoproc(t)))
		lwp_attach_brand_hdlrs(lwp);
}
Esempio n. 11
0
/*ARGSUSED*/
int
dtrace_getstackdepth(int aframes)
{
# if 1
	TODO();
	return 0;
# else
	struct frame *fp = (struct frame *)dtrace_getfp();
	struct frame *nextfp, *minfp, *stacktop;
	int depth = 0;
	int is_intr = 0;
	int on_intr;
	uintptr_t pc;

	if ((on_intr = CPU_ON_INTR(CPU)) != 0)
		stacktop = (struct frame *)(CPU->cpu_intr_stack + SA(MINFRAME));
	else
		stacktop = (struct frame *)curthread->t_stk;
	minfp = fp;

	aframes++;

	for (;;) {
		depth++;

		if (is_intr) {
			struct regs *rp = (struct regs *)fp;
			nextfp = (struct frame *)rp->r_fp;
			pc = rp->r_pc;
		} else {
			nextfp = (struct frame *)fp->fr_savfp;
			pc = fp->fr_savpc;
		}

		if (nextfp <= minfp || nextfp >= stacktop) {
			if (on_intr) {
				/*
				 * Hop from interrupt stack to thread stack.
				 */
				stacktop = (struct frame *)curthread->t_stk;
				minfp = (struct frame *)curthread->t_stkbase;
				on_intr = 0;
				continue;
			}
			break;
		}

		is_intr = pc - (uintptr_t)_interrupt < _interrupt_size ||
		    pc - (uintptr_t)_allsyscalls < _allsyscalls_size ||
		    pc - (uintptr_t)_cmntrap < _cmntrap_size;

		fp = nextfp;
		minfp = fp;
	}

	if (depth <= aframes)
		return (0);

	return (depth - aframes);
# endif
}
Esempio n. 12
0
 constexpr S() { { constexpr int j = 17; SA(j == 17); } }
Esempio n. 13
0
/** Sends a request to a RADIUS server and waits for the reply
 *
 * @param rh a handle to parsed configuration
 * @param data a pointer to a #SEND_DATA structure
 * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of
 *	any %PW_REPLY_MESSAGE received.
 * @param flags must be %AUTH or %ACCT
 * @return %OK_RC (0) on success, %TIMEOUT_RC on timeout %REJECT_RC on acess reject, or negative
 *	on failure as return value.
 */
int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
{
	int             sockfd;
	AUTH_HDR       *auth, *recv_auth;
	char           *server_name;	/* Name of server to query */
	struct sockaddr_storage our_sockaddr;
	struct addrinfo *auth_addr = NULL;
	socklen_t       salen;
	int             result = 0;
	int             total_length;
	int             length, pos;
	int             retry_max;
	unsigned	discover_local_ip;
	size_t		secretlen;
	char            secret[MAX_SECRET_LENGTH + 1];
	unsigned char   vector[AUTH_VECTOR_LEN];
	uint8_t          recv_buffer[BUFFER_LEN];
	uint8_t          send_buffer[BUFFER_LEN];
	char		our_addr_txt[50]; /* hold a text IP */
	char		auth_addr_txt[50]; /* hold a text IP */
	uint8_t		*attr;
	int		retries;
	VALUE_PAIR 	*vp;
	struct pollfd	pfd;
	double		start_time, timeout;

	server_name = data->server;
	if (server_name == NULL || server_name[0] == '\0')
		return ERROR_RC;

	if ((vp = rc_avpair_get(data->send_pairs, PW_SERVICE_TYPE, 0)) && \
	    (vp->lvalue == PW_ADMINISTRATIVE))
	{
		strcpy(secret, MGMT_POLL_SECRET);
		auth_addr = rc_getaddrinfo(server_name, flags==AUTH?PW_AI_AUTH:PW_AI_ACCT);
		if (auth_addr == NULL)
			return ERROR_RC;
	}
	else
	{
		if(data->secret != NULL)
		{
			strlcpy(secret, data->secret, MAX_SECRET_LENGTH);
		}
		/*
		else
		{
		*/
		if (rc_find_server_addr (rh, server_name, &auth_addr, secret, flags) != 0)
		{
			rc_log(LOG_ERR, "rc_send_server: unable to find server: %s", server_name);
			return ERROR_RC;
		}
		/*}*/
	}

	rc_own_bind_addr(rh, &our_sockaddr);
	discover_local_ip = 0;
	if (our_sockaddr.ss_family == AF_INET) {
		if (((struct sockaddr_in*)(&our_sockaddr))->sin_addr.s_addr == INADDR_ANY) {
			discover_local_ip = 1;
		}
	}

	DEBUG(LOG_ERR, "DEBUG: rc_send_server: creating socket to: %s", server_name);
	if (discover_local_ip) {
		result = rc_get_srcaddr(SA(&our_sockaddr), auth_addr->ai_addr);
		if (result != 0) {
			memset (secret, '\0', sizeof (secret));
			rc_log(LOG_ERR, "rc_send_server: cannot figure our own address");
			result = ERROR_RC;
			goto cleanup;
		}
	}

	sockfd = socket (our_sockaddr.ss_family, SOCK_DGRAM, 0);
	if (sockfd < 0)
	{
		memset (secret, '\0', sizeof (secret));
		rc_log(LOG_ERR, "rc_send_server: socket: %s", strerror(errno));
		result = ERROR_RC;
		goto cleanup;
	}

	if (our_sockaddr.ss_family == AF_INET)
		((struct sockaddr_in*)&our_sockaddr)->sin_port = 0;
	else
		((struct sockaddr_in6*)&our_sockaddr)->sin6_port = 0;

	if (bind(sockfd, SA(&our_sockaddr), SS_LEN(&our_sockaddr)) < 0)
	{
		close (sockfd);
		memset (secret, '\0', sizeof (secret));
		rc_log(LOG_ERR, "rc_send_server: bind: %s: %s", server_name, strerror(errno));
		result = ERROR_RC;
		goto cleanup;
	}

	retry_max = data->retries;	/* Max. numbers to try for reply */
	retries = 0;			/* Init retry cnt for blocking call */

	if (data->svc_port) {
		if (our_sockaddr.ss_family == AF_INET)
			((struct sockaddr_in*)auth_addr->ai_addr)->sin_port = htons ((unsigned short) data->svc_port);
		else
			((struct sockaddr_in6*)auth_addr->ai_addr)->sin6_port = htons ((unsigned short) data->svc_port);
	}

	/*
	 * Fill in NAS-IP-Address (if needed)
	 */
	if (rc_avpair_get(data->send_pairs, PW_NAS_IP_ADDRESS, 0) == NULL &&
	    rc_avpair_get(data->send_pairs, PW_NAS_IPV6_ADDRESS, 0) == NULL) {
		if (our_sockaddr.ss_family == AF_INET) {
			uint32_t ip;
			ip = *((uint32_t*)(&((struct sockaddr_in*)&our_sockaddr)->sin_addr));
			ip = ntohl(ip);

			rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IP_ADDRESS,
			    &ip, 0, 0);
		} else {
			void *p;
			p = &((struct sockaddr_in6*)&our_sockaddr)->sin6_addr;

			rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IPV6_ADDRESS,
			    p, 0, 0);
		}
	}

	/* Build a request */
	auth = (AUTH_HDR *) send_buffer;
	auth->code = data->code;
	auth->id = data->seq_nbr;

	if (data->code == PW_ACCOUNTING_REQUEST)
	{
		total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;

		auth->length = htons ((unsigned short) total_length);

		memset((char *) auth->vector, 0, AUTH_VECTOR_LEN);
		secretlen = strlen (secret);
		memcpy ((char *) auth + total_length, secret, secretlen);
		rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen);
		memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
	}
	else
	{
		rc_random_vector (vector);
		memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);

		total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;

		auth->length = htons ((unsigned short) total_length);
	}

	getnameinfo(SA(&our_sockaddr), SS_LEN(&our_sockaddr), NULL, 0, our_addr_txt, sizeof(our_addr_txt), NI_NUMERICHOST);
	getnameinfo(auth_addr->ai_addr, auth_addr->ai_addrlen, NULL, 0, auth_addr_txt, sizeof(auth_addr_txt), NI_NUMERICHOST);

	DEBUG(LOG_ERR, "DEBUG: local %s : 0, remote %s : %u\n", 
	      our_addr_txt, auth_addr_txt, data->svc_port);

	for (;;)
	{
		do {
			result = sendto (sockfd, (char *) auth, (unsigned int)total_length, 
				(int) 0, SA(auth_addr->ai_addr), auth_addr->ai_addrlen);
		} while (result == -1 && errno == EINTR);
		if (result == -1) {
			rc_log(LOG_ERR, "%s: socket: %s", __FUNCTION__, strerror(errno));
		}

		pfd.fd = sockfd;
		pfd.events = POLLIN;
		pfd.revents = 0;
		
		if(data->timeout_ms > 0){
                        start_time = rc_getctime_ms();
                        for (timeout = data->timeout_ms; timeout > 0;timeout -= rc_getctime_ms() - start_time) {
                            result = poll(&pfd, 1, timeout );
                            if (result != -1 || errno != EINTR)
                                    break;
                    }
                }else{
                    start_time = rc_getctime();
                    for (timeout = data->timeout; timeout > 0;timeout -= rc_getctime() - start_time) {
                            result = poll(&pfd, 1, timeout* 1000);
                            if (result != -1 || errno != EINTR)
                                    break;
                    }
                }
                
		if (result == -1)
		{
			rc_log(LOG_ERR, "rc_send_server: poll: %s", strerror(errno));
			memset (secret, '\0', sizeof (secret));
			close (sockfd);
			result = ERROR_RC;
			goto cleanup;
		}
		if (result == 1 && (pfd.revents & POLLIN) != 0)
			break;

		/*
		 * Timed out waiting for response.  Retry "retry_max" times
		 * before giving up.  If retry_max = 0, don't retry at all.
		 */
		if (retries++ >= retry_max)
		{
			rc_log(LOG_ERR,
				"rc_send_server: no reply from RADIUS server %s:%u",
				 auth_addr_txt, data->svc_port);
			close (sockfd);
			memset (secret, '\0', sizeof (secret));
			result = TIMEOUT_RC;
			goto cleanup;
		}
	}
	salen = auth_addr->ai_addrlen;
	do {
		length = recvfrom (sockfd, (char *) recv_buffer,
				   (int) sizeof (recv_buffer),
				   (int) 0, SA(auth_addr->ai_addr), &salen);
	} while(length == -1 && errno == EINTR);

	if (length <= 0)
	{
		rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: %s", server_name,\
			 data->svc_port, strerror(errno));
		close (sockfd);
		memset (secret, '\0', sizeof (secret));
		result = ERROR_RC;
		goto cleanup;
	}

	recv_auth = (AUTH_HDR *)recv_buffer;

	if (length < AUTH_HDR_LEN || length < ntohs(recv_auth->length)) {
		rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: reply is too short",
		    server_name, data->svc_port);
		close(sockfd);
		memset(secret, '\0', sizeof(secret));
		result = ERROR_RC;
		goto cleanup;
	}

	/*
	 *	If UDP is larger than RADIUS, shorten it to RADIUS.
	 */
	if (length > ntohs(recv_auth->length)) length = ntohs(recv_auth->length);

	/*
	 *	Verify that it's a valid RADIUS packet before doing ANYTHING with it.
	 */
	attr = recv_buffer + AUTH_HDR_LEN;
	while (attr < (recv_buffer + length)) {
		if (attr[0] == 0) {
			rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute zero is invalid",
			       server_name, data->svc_port);
			close(sockfd);
			memset(secret, '\0', sizeof(secret));
			return ERROR_RC;
		}

		if (attr[1] < 2) {
			rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute length is too small",
			       server_name, data->svc_port);
			close(sockfd);
			memset(secret, '\0', sizeof(secret));
			return ERROR_RC;
		}

		if ((attr + attr[1]) > (recv_buffer + length)) {
			rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: attribute overflows the packet",
			       server_name, data->svc_port);
			close(sockfd);
			memset(secret, '\0', sizeof(secret));
			return ERROR_RC;
		}

		attr += attr[1];
	}

	result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr);

	length = ntohs(recv_auth->length)  - AUTH_HDR_LEN;
	if (length > 0) {
		data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data,
		    length, 0);
	} else {
		data->receive_pairs = NULL;
	}

	close (sockfd);
	memset (secret, '\0', sizeof (secret));

	if (result != OK_RC) {
		goto cleanup;
	}

	if (msg) {
		*msg = '\0';
		pos = 0;
		vp = data->receive_pairs;
		while (vp)
		{
			if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0)))
			{
				strappend(msg, PW_MAX_MSG_SIZE, &pos, vp->strvalue);
				strappend(msg, PW_MAX_MSG_SIZE, &pos, "\n");
				vp = vp->next;
			}
		}
	}

	if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
		(recv_auth->code == PW_PASSWORD_ACK) ||
		(recv_auth->code == PW_ACCOUNTING_RESPONSE))
	{
		result = OK_RC;
	}
	else if ((recv_auth->code == PW_ACCESS_REJECT) ||
		(recv_auth->code == PW_PASSWORD_REJECT))
	{
		result = REJECT_RC;
	}
	else
	{
		result = BADRESP_RC;
	}

 cleanup:
 	if (auth_addr)
 		freeaddrinfo(auth_addr);

	return result;
}
Esempio n. 14
0
/* ////////////////////////////////////////////////////////////////////////////
   -- Testing dlat2s and slat2d
*/
int main( int argc, char** argv )
{
    #define  A(i_,j_) ( A + (i_) + (j_)*lda)
    #define SA(i_,j_) (SA + (i_) + (j_)*lda)
    
    TESTING_INIT();
    
    real_Double_t   gbytes, gpu_perf, gpu_time, cpu_perf, cpu_time;
    double error, work[1];
    float serror, swork[1];
    double c_neg_one = MAGMA_D_NEG_ONE;
    float  s_neg_one = MAGMA_S_NEG_ONE;
    magma_int_t ione = 1;
    magma_int_t n, lda, ldda, size, info;
    magma_int_t ISEED[4] = {0,0,0,1};
    magma_int_t status = 0;
    float   *SA, *SR;
    double   *A,  *R;
    float  *dSA;
    double  *dA;
    
    magma_opts opts;
    parse_opts( argc, argv, &opts );
    
    magma_uplo_t uplo[] = { MagmaLower, MagmaUpper };
    
    printf("func    uplo     N     CPU GB/s (ms)       GPU GB/s (ms)     ||R||_F\n");
    printf("=====================================================================\n");
    for( int iuplo = 0; iuplo < 2; ++iuplo ) {
      for( int itest = 0; itest < opts.ntest; ++itest ) {
        for( int iter = 0; iter < opts.niter; ++iter ) {
            n = opts.nsize[itest];
            lda  = n;
            ldda = ((n+31)/32)*32;
            // 0.5*(n+1)*n double-real loads and 0.5*(n+1)*n single-real stores (and vice-versa for slat2d)
            gbytes = (real_Double_t) 0.5*(n+1)*n * (sizeof(double) + sizeof(float)) / 1e9;
            size = ldda*n;  // ldda >= lda
            
            TESTING_MALLOC_CPU(  SA, float,  size );
            TESTING_MALLOC_CPU(   A, double, size );
            TESTING_MALLOC_CPU(  SR, float,  size );
            TESTING_MALLOC_CPU(   R, double, size );
            
            TESTING_MALLOC_DEV( dSA, float,  size );
            TESTING_MALLOC_DEV(  dA, double, size );
            
            lapackf77_dlarnv( &ione, ISEED, &size,  A );
            lapackf77_slarnv( &ione, ISEED, &size, SA );
            
            magma_dsetmatrix( n, n, A,  lda, dA,  ldda );
            magma_ssetmatrix( n, n, SA, lda, dSA, ldda );
            
            /* =====================================================================
               Performs operation using LAPACK dlat2s
               =================================================================== */
            info = 0;
            cpu_time = magma_wtime();
            lapackf77_dlat2s( lapack_uplo_const(uplo[iuplo]), &n, A, &lda, SA, &lda, &info );
            cpu_time = magma_wtime() - cpu_time;
            cpu_perf = gbytes / cpu_time;
            if (info != 0)
                printf("lapackf77_dlat2s returned error %d: %s.\n",
                       (int) info, magma_strerror( info ));
            
            /* ====================================================================
               Performs operation using MAGMA dlat2s
               =================================================================== */
            gpu_time = magma_sync_wtime(0);
            magmablas_dlat2s( uplo[iuplo], n, dA, ldda, dSA, ldda, &info );
            gpu_time = magma_sync_wtime(0) - gpu_time;
            gpu_perf = gbytes / gpu_time;
            if (info != 0)
                printf("magmablas_dlat2s returned error %d: %s.\n",
                       (int) info, magma_strerror( info ));
            
            magma_sgetmatrix( n, n, dSA, ldda, SR, lda );
            
            if ( opts.verbose ) {
                printf( "A=  " );  magma_dprint( n, n, A,  lda );
                printf( "SA= " );  magma_sprint( n, n, SA, lda );
                printf( "dA= " );  magma_dprint_gpu( n, n, dA,  ldda );
                printf( "dSA=" );  magma_sprint_gpu( n, n, dSA, ldda );
            }
            
            /* =====================================================================
               compute error |SA_magma - SA_lapack|
               should be zero if both are IEEE compliant
               =================================================================== */
            blasf77_saxpy( &size, &s_neg_one, SA, &ione, SR, &ione );
            serror = lapackf77_slange( "Fro", &n, &n, SR, &lda, swork );
            
            printf( "dlat2s %5s %5d   %7.2f (%7.2f)   %7.2f (%7.2f)   %8.2e   %s\n",
                    lapack_uplo_const(uplo[iuplo]), (int) n,
                    cpu_perf, cpu_time*1000., gpu_perf, gpu_time*1000.,
                    serror, (serror == 0 ? "ok" : "failed") );
            status += ! (serror == 0);
            
            
            /* =====================================================================
               Reset matrices
               =================================================================== */
            lapackf77_dlarnv( &ione, ISEED, &size,  A );
            lapackf77_slarnv( &ione, ISEED, &size, SA );
            
            magma_dsetmatrix( n, n, A,  lda, dA,  ldda );
            magma_ssetmatrix( n, n, SA, lda, dSA, ldda );
            
            /* =====================================================================
               Performs operation using LAPACK slat2d
               LAPACK doesn't implement slat2d; use our own simple implementation.
               =================================================================== */
            cpu_time = magma_wtime();
            if ( uplo[iuplo] == MagmaLower ) {
                for( int j=0; j < n; ++j ) {
                    for( int i=j; i < n; ++i ) {
                        *A(i,j) = MAGMA_D_MAKE( real(*SA(i,j)), imag(*SA(i,j)) );
                    }
                }
            }
            else { // upper
                for( int j=0; j < n; ++j ) {
                    for( int i=0; i <= j; ++i ) {
                        *A(i,j) = MAGMA_D_MAKE( real(*SA(i,j)), imag(*SA(i,j)) );
                    }
                }
            }
            cpu_time = magma_wtime() - cpu_time;
            cpu_perf = gbytes / cpu_time;
            if (info != 0)
                printf("lapackf77_slat2d returned error %d: %s.\n",
                       (int) info, magma_strerror( info ));
            
            /* ====================================================================
               Performs operation using MAGMA slat2d
               =================================================================== */
            magma_ssetmatrix( n, n, SA, lda, dSA, ldda );
            
            gpu_time = magma_sync_wtime(0);
            magmablas_slat2d( uplo[iuplo], n, dSA, ldda, dA, ldda, &info );
            gpu_time = magma_sync_wtime(0) - gpu_time;
            gpu_perf = gbytes / gpu_time;
            if (info != 0)
                printf("magmablas_slat2d returned error %d: %s.\n",
                       (int) info, magma_strerror( info ));
            
            magma_dgetmatrix( n, n, dA, ldda, R, lda );
            
            if ( opts.verbose ) {
                printf( "A=  " );  magma_dprint( n, n, A,  lda );
                printf( "SA= " );  magma_sprint( n, n, SA, lda );
                printf( "dA= " );  magma_dprint_gpu( n, n, dA,  ldda );
                printf( "dSA=" );  magma_sprint_gpu( n, n, dSA, ldda );
            }
            
            /* =====================================================================
               compute error |A_magma - A_lapack|
               should be zero if both are IEEE compliant
               =================================================================== */
            blasf77_daxpy( &size, &c_neg_one, A, &ione, R, &ione );
            error = lapackf77_dlange( "Fro", &n, &n, R, &lda, work );
            
            printf( "slat2d %5s %5d   %7.2f (%7.2f)   %7.2f (%7.2f)   %8.2e   %s\n",
                    lapack_uplo_const(uplo[iuplo]), (int) n,
                    cpu_perf, cpu_time*1000., gpu_perf, gpu_time*1000.,
                    error, (error == 0 ? "ok" : "failed") );
            status += ! (error == 0);
            
            TESTING_FREE_CPU(  SA );
            TESTING_FREE_CPU(   A );
            TESTING_FREE_CPU(  SR );
            TESTING_FREE_CPU(   R );
                                 
            TESTING_FREE_DEV( dSA );
            TESTING_FREE_DEV(  dA );
            printf( "\n" );
            fflush( stdout );
        }
        if ( opts.niter > 1 ) {
            printf( "\n" );
        }
      }
      printf( "\n" );
    }
    
    TESTING_FINALIZE();
    return status;
}
Esempio n. 15
0
static void
initTask(Task * task)
{
   static jmp_buf stkswitch;

   if (task->isInited)
      return;

   task->isInited = 1;		/*   we are initialized */

   /*   switch to private stack now */

   if (!setjmp(stkswitch))
   {
      unsigned char *sp = ((unsigned char *) task->stack) + task->stacklen;

      sp -= WINDOWSIZE + SA(MINFRAME);
      sp = (unsigned char *) ((unsigned long) (sp) & 0xfffffff8);
#undef UNKNOWN_SYSTEM
#define UNKNOWN_SYSTEM
#ifdef __TURBOC__
      uchar far *farstk = (uchar far *) sp;

      stkswitch[0].j_ss = FP_SEG(farstk);
      stkswitch[0].j_sp = FP_OFF(farstk);
#undef UNKNOWN_SYSTEM
#endif
#ifdef OS_LINUX
#ifdef ARCH_S390
      stkswitch[0].__jmpbuf[0].gregs[9] = (unsigned int) (stack + stklen - sizeof(jmp_buf));
#else
      stkswitch[0].__jmpbuf[4] = (int) sp;
#endif
#undef UNKNOWN_SYSTEM
#endif
#ifdef OS_BSDI
      stkswitch[2] = (unsigned) (sp);
#undef UNKNOWN_SYSTEM
#endif
#ifdef OS_FREEBSD
      stkswitch[0]._jb[2] = (unsigned) (sp);
#undef UNKNOWN_SYSTEM
#endif
#ifdef OS_NETBSD
      ((unsigned *) &stkswitch)[2] = (unsigned) (sp);
#undef UNKNOWN_SYSTEM
#endif
#ifdef OS_OPENBSD
      ((unsigned *) &stkswitch)[2] = (unsigned) (sp);
#undef UNKNOWN_SYSTEM
#endif
#ifdef OS_SUNOS
      stkswitch[0].__fp = task->stack + task->stacklen - sizeof(jmp_buf);
#undef UNKNOWN_SYSTEM
#endif
#ifdef OS_SOLARIS_8
#if defined(sparc) || defined(__sparc)
      stkswitch[1] = (long) sp;
      stkswitch[2] = (long) &call_curr_task;
#undef UNKNOWN_SYSTEM
#elif defined(i386) || defined(__i386)
      stkswitch[4] = (long) sp;
      stkswitch[5] = (long) &call_curr_task;
#undef UNKNOWN_SYSTEM
#endif
#endif
#ifdef _WIN32
      stkswitch[7] = (unsigned) (sp);
#undef UNKNOWN_SYSTEM
#endif
#ifdef DJGPP
      stkswitch[0].__esp = (unsigned) (sp);
#undef UNKNOWN_SYSTEM
#endif

      /*  ((unsigned*)&stkswitch)[ SP_IN_JMPBUF_NO ] = (unsigned int)stack + stklen - sizeof(jmp_buf); */
#ifdef UNKNOWN_SYSTEM
#error Unknown System!
#endif

      longjmp(stkswitch, 1);
   }

   /*  now is in private stack, start task running ... */
   callTaskRun(currTask);
   /*   ... and never return */
}
Esempio n. 16
0
::libmaus2::bitio::CompactArray::unique_ptr_type bwtDivSufSort(::libmaus2::bitio::CompactArray const & C, bool const verbose = false)
{
	if ( C.n < (1ull << 31) )
	{
		typedef ::libmaus2::bitio::CompactArray::const_iterator text_const_iterator;
		typedef ::libmaus2::bitio::CompactArray::iterator text_iterator;
		typedef int32_t const * sa_const_iterator;
		typedef int32_t * sa_iterator;
		
		uint64_t const bitwidth = 64;
		typedef ::libmaus2::suffixsort::DivSufSort<bitwidth,text_iterator,text_const_iterator,sa_iterator,sa_const_iterator> sort_type;

		uint64_t const n = C.size();
		uint64_t const b = C.getB();
		::libmaus2::autoarray::AutoArray< int32_t > SA(n,false);

		if ( verbose )
			std::cerr << "Running divsufsort...";
		::libmaus2::timing::RealTimeClock drtc; drtc.start();
		sort_type::divsufsort ( text_const_iterator(&C), SA.get(), n );
		if ( verbose )
			std::cerr << "done, time " << drtc.getElapsedSeconds() << std::endl;
		
		::libmaus2::bitio::CompactArray::unique_ptr_type BWT(new ::libmaus2::bitio::CompactArray(n,b));
		
		for ( uint64_t i = 0; i < n; ++i )
			if ( SA.get(i) )
				BWT -> set ( i, C.get(SA.get(i)-1) );
			else
				BWT -> set ( i, C.get(n-1) );
		
		return UNIQUE_PTR_MOVE(BWT);
	}
	else
	{
		typedef ::libmaus2::bitio::CompactArray::const_iterator text_const_iterator;
		typedef ::libmaus2::bitio::CompactArray::iterator text_iterator;
		typedef int64_t const * sa_const_iterator;
		typedef int64_t * sa_iterator;
		
		uint64_t const bitwidth = 64;
		typedef ::libmaus2::suffixsort::DivSufSort<bitwidth,text_iterator,text_const_iterator,sa_iterator,sa_const_iterator> sort_type;

		uint64_t const n = C.size();
		uint64_t const b = C.getB();
		::libmaus2::autoarray::AutoArray< int64_t > SA(n,false);

		if ( verbose )
			std::cerr << "Running divsufsort...";
		::libmaus2::timing::RealTimeClock drtc; drtc.start();
		sort_type::divsufsort ( text_const_iterator(&C), SA.get(), n );
		if ( verbose )
			std::cerr << "done, time " << drtc.getElapsedSeconds() << std::endl;
		
		::libmaus2::bitio::CompactArray::unique_ptr_type BWT(new ::libmaus2::bitio::CompactArray(n,b));
		
		for ( uint64_t i = 0; i < n; ++i )
			if ( SA.get(i) )
				BWT -> set ( i, C.get(SA.get(i)-1) );
			else
				BWT -> set ( i, C.get(n-1) );
		
		return UNIQUE_PTR_MOVE(BWT);
	
	}
}
Esempio n. 17
0
/*
 * This function runs in the parent context and updates the global_no_access
 * list. 
 */
void process_sensor( const struct service *sp, const union xsockaddr *addr)
{
   const char *func = "process_sensor";

   if (SC_DENY_TIME(SVC_CONF(sp)) != 0)   /* 0 simply logs it   */
   {
      if ( pset_count( global_no_access ) < MAX_GLOBAL_NO_ACCESS)
      {
         int item_matched = addrlist_match( global_no_access, SA(addr) );

	 if ( item_matched == 0)
	 {   /* no match...adding to the list   */
            char *dup_addr = new_string(xaddrname( addr ) );

	    if (dup_addr == NULL )
               return ;

	    if (addrlist_add(global_no_access, dup_addr) == FAILED)
               msg(LOG_ERR, func,
                  "Failed adding %s to the global_no_access list", dup_addr);
            else
            {
               time_t nowtime;
               char time_buf[40], *tmp;

	       nowtime = time(NULL);
	       msg(LOG_CRIT, func,
	           "Adding %s to the global_no_access list for %d minutes",
	            dup_addr, SC_DENY_TIME(SVC_CONF(sp)));

	       if (SC_DENY_TIME(SVC_CONF(sp)) == -1)
                    strcpy(time_buf, "-1");
               else
                    strx_nprint(time_buf, 38, "%ld",
                       (time_t)nowtime+(60*SC_DENY_TIME(SVC_CONF(sp))));

	       tmp = new_string(time_buf);
               if (tmp != NULL)
               {
                  if (pset_add(global_no_access_time, tmp) == NULL)
                  {
                     msg(LOG_ERR, func,
                         "Failed adding %s to the global_no_access_time list. "
                         "global_no_access list is broken, xinetd needs "
			 "restarting.", dup_addr);
                 /* ideally, we should rollback the previous addr addition.   */
                  }
               }
	       if (pset_count(global_no_access) && (timer_id == 0) )
                  timer_id = xtimer_add( scrub_global_access_list, 60 );
            }
            free(dup_addr);
         }
         else
	 {
	    /* Here again, eh?...update time stamp. */
            char *exp_time;
	    time_t stored_time;

	    item_matched--; /* Is # plus 1, to even get here must be >= 1 */
            exp_time = pset_pointer( global_no_access_time, item_matched ) ;
            if (exp_time == NULL)
               return ;

            if ( parse_base10(exp_time, (int *)&stored_time) )
            {  /* if never let them off, bypass */
               if (stored_time != -1)
               {
                  time_t nowtime, new_time;

                  nowtime = time(NULL);
                  new_time = (time_t)nowtime+(60*SC_DENY_TIME(SVC_CONF(sp)));                     if (difftime(new_time, (time_t)stored_time) > 0.0)
	          {   /* new_time is longer save it   */
		     char time_buf[40], *new_exp_time;

		     strx_nprint(time_buf, 38, "%ld", (long)new_time);
		     new_exp_time = new_string(time_buf);
		     if ( new_exp_time )
		     {
		        free(exp_time);
			global_no_access_time->ptrs[ 
                        (unsigned)item_matched ] = new_exp_time;
                     }
                  }
               }
            }
         }
      }
      else
         msg(LOG_ERR, func, "Maximum global_no_access count reached.");
   }
}
Esempio n. 18
0
File: spki.c Progetto: macssh/macssh
struct sexp *
spki_make_public_key(struct verifier *verifier)
{
  return sexp_l(2, SA(PUBLIC_KEY),
		PUBLIC_SPKI_KEY(verifier), -1);
}
Esempio n. 19
0
/*
 * Get an interrupt thread and swith to it. It's called from do_interrupt().
 * The IF flag is cleared and thus all maskable interrupts are blocked at
 * the time of calling.
 */
static caddr_t
apix_intr_thread_prolog(struct cpu *cpu, uint_t pil, caddr_t stackptr)
{
	apix_impl_t *apixp = apixs[cpu->cpu_id];
	struct machcpu *mcpu = &cpu->cpu_m;
	hrtime_t now = tsc_read();
	kthread_t *t, *volatile it;

	ASSERT(pil > mcpu->mcpu_pri && pil > cpu->cpu_base_spl);

	apixp->x_intr_pending &= ~(1 << pil);
	ASSERT((cpu->cpu_intr_actv & (1 << pil)) == 0);
	cpu->cpu_intr_actv |= (1 << pil);
	mcpu->mcpu_pri = pil;

	/*
	 * Get set to run interrupt thread.
	 * There should always be an interrupt thread since we
	 * allocate one for each level on the CPU.
	 */
	/* t_intr_start could be zero due to cpu_intr_swtch_enter. */
	t = cpu->cpu_thread;
	if ((t->t_flag & T_INTR_THREAD) && t->t_intr_start != 0) {
		hrtime_t intrtime = now - t->t_intr_start;
		mcpu->intrstat[pil][0] += intrtime;
		cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
		t->t_intr_start = 0;
	}

	/*
	 * Push interrupted thread onto list from new thread.
	 * Set the new thread as the current one.
	 * Set interrupted thread's T_SP because if it is the idle thread,
	 * resume() may use that stack between threads.
	 */

	ASSERT(SA((uintptr_t)stackptr) == (uintptr_t)stackptr);

	t->t_sp = (uintptr_t)stackptr;	/* mark stack in curthread for resume */

	/*
	 * Note that the code in kcpc_overflow_intr -relies- on the
	 * ordering of events here - in particular that t->t_lwp of
	 * the interrupt thread is set to the pinned thread *before*
	 * curthread is changed.
	 */
	it = cpu->cpu_intr_thread;
	cpu->cpu_intr_thread = it->t_link;
	it->t_intr = t;
	it->t_lwp = t->t_lwp;

	/*
	 * (threads on the interrupt thread free list could have state
	 * preset to TS_ONPROC, but it helps in debugging if
	 * they're TS_FREE.)
	 */
	it->t_state = TS_ONPROC;

	cpu->cpu_thread = it;

	/*
	 * Initialize thread priority level from intr_pri
	 */
	it->t_pil = (uchar_t)pil;
	it->t_pri = (pri_t)pil + intr_pri;
	it->t_intr_start = now;

	return (it->t_stk);
}
Esempio n. 20
0
int main(int argc, char * argv[]){
  int opt;
  bool err = false;
  string inputFilename, outputFilename, line;
  uInt gramLen = 2;
  enum AlgoType atype = NONE;
  enum InputType itype = INPUT_SLP;
  bool sort_output = false;
  while((opt = getopt(argc, argv, "hcnxsq:f:ta:")) != -1){
    switch(opt){
    case 'h': display_usage(argc, argv); return 0; break;
    case 'q': gramLen = atoi(optarg); break;
    case 'f': inputFilename = optarg; break;
    case 't': itype = INPUT_PLAINTEXT; break; 
    case 's': sort_output = true; break;
    case 'a':
      if(atoi(optarg) <= 4) atype = static_cast<enum AlgoType>(atoi(optarg)); break;
    default: err = true;
    }
  }
  if(atype == NONE){ 
    cerr << "ERROR: algorithm type (1 - 4) must be specified with -a" << endl;
    err = true; 
  }
  if(err){
    display_usage(argc, argv);
    return 1;
  }
  posfreq rp;
  gramfreq rg;
  string t;
  vector<posfreq> pfs;
  string str;
  str.clear();
  vector<uInt> weights;
  std::map<substr, uInt, substrCmp> * counts = NULL;
  if (itype == INPUT_PLAINTEXT){
    ifstream ifile(inputFilename.c_str(), fstream::in);
    while(ifile.good()){
      char c = ifile.get();
      if(ifile.good()){ str.push_back(c); }
    }
    if (atype == NAIVE_GRAMMAP){ // NMP
      substrCmp compclass(str);
      counts = new std::map<substr, uInt, substrCmp>(compclass);
      // std::map<substr, uInt, substrCmp>  counts1(compclass);
      qgramGM::Frequent(gramLen, str, *counts);
    }else if (atype == NAIVE_SUFFIXARRAY){ // NSA
      SuffixArrayAux SA(str);
      qgramSA::Frequent(SA, gramLen, pfs);
    }else{
      assert(atype > 2);
    }
  }else{
    SLPFastQgramStats slp(inputFilename.c_str());
    if (atype == NAIVE_SUFFIXARRAY){ // nsa
      slp.toString(str);
      SuffixArrayAux SA(str);
      qgramSA::Frequent(SA, gramLen, pfs);
    }else if (atype == NAIVE_GRAMMAP){ // nmp
      slp.toString(str);
      substrCmp compclass(str);
      counts = new std::map<substr, uInt, substrCmp>(compclass);
      // std::map<substr, uInt, substrCmp>  counts1(compclass);
      qgramGM::Frequent(gramLen, str, *counts);
    }else { // for slp
      slp.prepare(gramLen);
      qgramSLPFast::makeGramStrWeights(slp, str, weights);
      if (atype == SLP_GRAMMAP){ //smp
        substrCmp compclass(str);
        counts = new std::map<substr, uInt, substrCmp>(compclass);
        qgramWGM::Frequent(gramLen, str, weights, *counts);
      }else if (atype == SLP_SUFFIXARRAY){ // ssa
        SuffixArrayAux slpSA(str);
        qgramSA::Frequent(slpSA, gramLen, weights, pfs);

      }
    }
  }

  if (atype == NAIVE_GRAMMAP || atype == SLP_GRAMMAP){
    if (!sort_output){
      map<substr, uInt, substrCmp>::const_iterator itr;
      for(itr = counts->begin(); itr != counts->end(); itr++){
        const substr & s = (*itr).first;
        cout << "\"" << str.substr(s.p, gramLen) << "\","
             << (*itr).second << endl;
      }
    }else{
      vector<gramfreq> gfs;
      map<substr, uInt, substrCmp>::const_iterator itr;
      for(itr = counts->begin(); itr != counts->end(); itr++){
        gramfreq gf;
        gf.gram = str.substr((*itr).first.p, gramLen);
        gf.freq = (*itr).second;
        gfs.push_back(gf);
      }
      // cout << "gfs.size()=" << gfs.size() << " counts.size()" << counts->size() << endl;
      sort(gfs.begin(), gfs.end(), greater<gramfreq>());
      for(uInt i = 0; i < gfs.size(); i++){
        cout << "\"" << gfs[i].gram << "\","
             << gfs[i].freq << endl;
      }
    }
  }else{
    if (sort_output) sort(pfs.begin(), pfs.end(), greater<posfreq>());
    for(uInt i = 0; i < pfs.size(); i++){
      cout << "\"" << str.substr(pfs[i].pos, gramLen) << "\","
           << pfs[i].freq << endl;
    }
  }
  return 0;
}
Esempio n. 21
0
void indexTranscriptsSA(ParserT* parser,
            		std::string& outputDir,
                        std::mutex& iomutex) {
    // Seed with a real random value, if available
    std::random_device rd;

    // Create a random uniform distribution
    std::default_random_engine eng(rd());

    std::uniform_int_distribution<> dis(0, 3);

    uint32_t n{0};
    uint32_t k = rapmap::utils::my_mer::k();
    std::vector<std::string> transcriptNames;
    std::vector<uint32_t> transcriptStarts;
    //std::vector<uint32_t> positionIDs;
    constexpr char bases[] = {'A', 'C', 'G', 'T'};
    uint32_t polyAClipLength{10};
    uint32_t numPolyAsClipped{0};
    std::string polyA(polyAClipLength, 'A');

    using TranscriptList = std::vector<uint32_t>;
    using eager_iterator = MerMapT::array::eager_iterator;
    using KmerBinT = uint64_t;

    size_t numDistinctKmers{0};
    size_t numKmers{0};
    size_t currIndex{0};
    std::cerr << "\n[Step 1 of 4] : counting k-mers\n";

    //rsdic::RSDicBuilder rsdb;
    std::vector<uint32_t> onePos; // Positions in the bit array where we should write a '1'
    fmt::MemoryWriter txpSeqStream;
    {
        ScopedTimer timer;
        while(true) {
            typename ParserT::job j(*parser);
            if(j.is_empty()) break;
            for(size_t i = 0; i < j->nb_filled; ++i) { // For each sequence
                std::string& readStr = j->data[i].seq;
                readStr.erase(std::remove_if(readStr.begin(), readStr.end(),
                               [](const char a) -> bool {
                                    return !(isprint(a));
                                }), readStr.end());
                // Do Kallisto-esque clipping of polyA tails
                if (readStr.size() > polyAClipLength and
                        readStr.substr(readStr.length() - polyAClipLength) == polyA) {

                    auto newEndPos = readStr.find_last_not_of("Aa");
                    // If it was all As
                    if (newEndPos == std::string::npos) {
                        readStr.resize(0);
                    } else {
                        readStr.resize(newEndPos + 1);
                    }
                    ++numPolyAsClipped;
                }

                uint32_t readLen  = readStr.size();
                uint32_t txpIndex = n++;

		// The name of the current transcript
                transcriptNames.push_back(j->data[i].header);
		// The position at which this transcript starts
                transcriptStarts.push_back(currIndex);


                bool firstBase{true};
                rapmap::utils::my_mer mer;
                mer.polyT();
                for (size_t b = 0; b < readLen; ++b) {
                    readStr[b] = ::toupper(readStr[b]);
                    int c = jellyfish::mer_dna::code(readStr[b]);
                    // Replace non-ACGT bases with pseudo-random bases
                    if (jellyfish::mer_dna::not_dna(c)) {
                        char rbase = bases[dis(eng)];
                        c = jellyfish::mer_dna::code(rbase);
                        readStr[b] = rbase;
                    }
                    //positionIDs.push_back(txpIndex);
		    //rsdb.PushBack(0);
                }
                txpSeqStream << readStr;
                txpSeqStream << '$';
                //positionIDs.push_back(txpIndex);
		//rsdb.PushBack(1);
                currIndex += readLen + 1;
		onePos.push_back(currIndex - 1);
            }
            if (n % 10000 == 0) {
                std::cerr << "\r\rcounted k-mers for " << n << " transcripts";
            }
        }
    }
    std::cerr << "\n";

    std::cerr << "Clipped poly-A tails from " << numPolyAsClipped << " transcripts\n";

    // Put the concatenated text in a string
    std::string concatText = txpSeqStream.str();
    // And clear the stream
    txpSeqStream.clear();


    // Make our dense bit arrray
    BIT_ARRAY* bitArray = bit_array_create(concatText.length());
    for (auto p : onePos) {
	    bit_array_set_bit(bitArray, p);
    }

    /** SANITY CHECKS RELATED TO THE RANK structure **/
    /*
    uint64_t nextSetBit{0};
    uint64_t offset{0};
    auto numBits = bit_array_length(bitArray);
    while (offset < numBits and bit_array_find_next_set_bit(bitArray, offset, &nextSetBit)) {
	if (concatText[nextSetBit] != '$') {
		std::cerr << "Bit # " << nextSetBit << " is set to 1, but the "
			  << "corresponding character in the text is " << concatText[nextSetBit] << "\n";
	}
	offset = nextSetBit + 1;
    }

    if (bit_array_num_bits_set(bitArray) != onePos.size()) {
	std::cerr << "ERROR: Bit array has " << bit_array_num_bits_set(bitArray)
		  << " bits set, but this should be " << onePos.size() << "!\n";
	std::exit(1);
    }

    rank9b bitmap(bitArray->words, bitArray->num_of_bits);
    for (size_t i = 0; i < onePos.size() - 1; ++i) {
	    auto pos = onePos[i];
	    auto r = bitmap.rank(pos+1);

	    if (r != i+1) {
		std::cerr << "rank should be " << i+1 << " but it's " << r << "\n";
		std::cerr << "text is " << concatText[pos] < "\n\n";
		std::cerr << "bit vector says " << (bit_array_get_bit(bitArray, pos) ? '1' : '0') << "\n";
	    }
    }

    std::ofstream rsStream(outputDir + "rsdSafe.bin", std::ios::binary);
    {
        ScopedTimer timer;
        rsdic::RSDic rsd;
        rsdb.Build(rsd);
        rsd.Save(rsStream);
        std::cerr << "done\n";
    }
    rsStream.close();
    */
    /** END OF SANITY CHECK **/
    onePos.clear();
    onePos.shrink_to_fit();

    std::string rsFileName = outputDir + "rsd.bin";
    FILE* rsFile = fopen(rsFileName.c_str(), "w");
    {
        ScopedTimer timer;
        std::cerr << "Building rank-select dictionary and saving to disk ";
	bit_array_save(bitArray, rsFile);
        std::cerr << "done\n";
    }
    fclose(rsFile);
    bit_array_free(bitArray);


    std::ofstream seqStream(outputDir + "txpInfo.bin", std::ios::binary);
    {
        ScopedTimer timer;
        std::cerr << "Writing sequence data to file . . . ";
        cereal::BinaryOutputArchive seqArchive(seqStream);
        seqArchive(transcriptNames);
        seqArchive(transcriptStarts);
        //seqArchive(positionIDs);
        seqArchive(concatText);
        std::cerr << "done\n";
    }
    seqStream.close();

    // clear stuff we no longer need
    //positionIDs.clear();
    //positionIDs.shrink_to_fit();
    transcriptStarts.clear();
    transcriptStarts.shrink_to_fit();
    transcriptNames.clear();
    transcriptNames.shrink_to_fit();
    // done clearing


    // Build the suffix array
    size_t tlen = concatText.length();
    std::vector<int> SA(tlen, 0);
    std::ofstream saStream(outputDir + "sa.bin", std::ios::binary);
    {
        ScopedTimer timer;
        std::cerr << "Building suffix array . . . ";
        auto ret = sais(reinterpret_cast<unsigned char*>(
                        const_cast<char*>(concatText.c_str())),
                        SA.data(), tlen + 1);
        if (ret == 0) {
            std::cerr << "success\n";
            {
                ScopedTimer timer2;
                std::cerr << "saving to disk . . . ";
                cereal::BinaryOutputArchive saArchive(saStream);
                saArchive(SA);
		// don't actually need the LCP right now
                // saArchive(LCP);
                std::cerr << "done\n";
            }
        } else {
            std::cerr << "FAILURE: return code from sais() was " << ret << "\n";
	    std::exit(1);
        }
        std::cerr << "done\n";
    }
    saStream.close();

    // clear things we don't need
    //LCP.clear();
    // LCP.shrink_to_fit();
    // done clearing

    // Now, build the k-mer lookup table
    /*
    std::unordered_map<uint64_t,
                       rapmap::utils::SAInterval,
                       rapmap::utils::KmerKeyHasher> khash;
                       */
    google::dense_hash_map<uint64_t,
                        rapmap::utils::SAInterval,
                        rapmap::utils::KmerKeyHasher> khash;
    khash.set_empty_key(std::numeric_limits<uint64_t>::max());

    /*
    concatText.erase(std::remove_if(concatText.begin(),
                                    concatText.end(),
                                    [] (const char a) -> bool { return !isprint(a); }),
                     concatText.end());
                     */

    // The start and stop of the current interval
    uint32_t start = 0, stop = 0;
    // An iterator to the beginning of the text
    auto textB = concatText.begin();
    auto textE = concatText.end();
    // The current k-mer as a string
    rapmap::utils::my_mer mer;
    bool currentValid{false};
    std::string currentKmer;
    std::string nextKmer;
    while (stop < tlen) {
        // Check if the string starting at the
        // current position is valid (i.e. doesn't contain $)
        // and is <= k bases from the end of the string
        nextKmer = concatText.substr(SA[stop], k);
        if (nextKmer.length() == k and
            nextKmer.find_first_of('$') == std::string::npos) {
            // If this is a new k-mer, then hash the current k-mer
            if (nextKmer != currentKmer) {
                if (currentKmer.length() == k and
                    currentKmer.find_first_of('$') == std::string::npos) {
                    mer = rapmap::utils::my_mer(currentKmer);
                    auto bits = mer.get_bits(0, 2*k);
                    auto hashIt = khash.find(bits);
                    if (hashIt == khash.end()) {
                        if (start > 1) {
                            if (concatText.substr(SA[start-1], k) ==
                                concatText.substr(SA[start], k)) {
                                std::cerr << "T[SA["
                                          << start-1 << "]:" << k << "] = "
                                          << concatText.substr(SA[start-1], k)
                                          << " = T[SA[" << start << "]:" << k << "]\n";
                                std::cerr << "start = " << start << ", stop = " << stop << "\n";
                                std::cerr << "(1) THIS SHOULD NOT HAPPEN\n";
                                std::exit(1);
                            }
                        }
                        if (start == stop) {
                            std::cerr << "AHH (1) : Interval is empty! (start = " << start
                                      << ") = (stop =  " << stop << ")\n";
                        }
                        if (start == stop) {
                            std::cerr << "AHH (2) : Interval is empty! (start = " << start
                                << ") = (stop =  " << stop << ")\n";
                        }

                        khash[bits] = {start, stop};
                    } else {
                        std::cerr << "\nERROR (1): trying to add same suffix "
                                  << currentKmer << " (len = "
                                  << currentKmer.length() << ") multiple times!\n";
                        auto prevInt = hashIt->second;
                        std::cerr << "existing interval is ["
                                  << prevInt.begin << ", " << prevInt.end << ")\n";
                        for (auto x = prevInt.begin; x < prevInt.end; ++x) {
                            auto suff = concatText.substr(SA[x], k);
                            for (auto c : suff) {
                                std::cerr << "*" << c << "*";
                            }
                            std::cerr << " (len = " << suff.length() <<")\n";
                        }
                        std::cerr << "new interval is ["
                                  << start << ", " << stop << ")\n";
                        for (auto x = start; x < stop; ++x) {
                            auto suff = concatText.substr(SA[x], k);
                            for (auto c : suff) {
                                std::cerr << "*" << c << "*";
                            }
                            std::cerr << "\n";
                        }
                    }
                }
                currentKmer = nextKmer;
                start = stop;
            }
        } else {
            // If this isn't a valid suffix (contains a $)

            // If the previous interval was valid, put it
            // in the hash.
            if (currentKmer.length() == k and
                currentKmer.find_first_of('$') == std::string::npos) {
                mer = rapmap::utils::my_mer(currentKmer);
                auto bits = mer.get_bits(0, 2*k);
                auto hashIt = khash.find(bits);
                if (hashIt == khash.end()) {
                    if (start > 2) {
                        if (concatText.substr(SA[start-1], k) ==
                            concatText.substr(SA[start], k)) {
                            std::cerr << "T[SA["
                                << start-1 << "]:" << k << "] = "
                                << concatText.substr(SA[start-1], k)
                                << " = T[SA[" << start << "]:" << k << "]\n";
                            std::cerr << "start = " << start << ", stop = " << stop << "\n";
                            std::cerr << "(2) THIS SHOULD NOT HAPPEN\n";
                            std::exit(1);
                        }
                    }
                    khash[bits] = {start, stop};
                } else {
                    std::cerr << "\nERROR (2): trying to add same suffix "
                              << currentKmer << "multiple times!\n";
                    auto prevInt = hashIt->second;
                    std::cerr << "existing interval is ["
                        << prevInt.begin << ", " << prevInt.end << ")\n";
                    for (auto x = prevInt.begin; x < prevInt.end; ++x) {
                        std::cerr << concatText.substr(SA[x], k) << "\n";
                    }
                    std::cerr << "new interval is ["
                        << start << ", " << stop << ")\n";
                    for (auto x = start; x < stop; ++x) {
                        std::cerr << concatText.substr(SA[x], k) << "\n";
                    }
                }

            }
            // The current interval is invalid and empty
            currentKmer = nextKmer;
            start = stop;
        }
        if (stop % 1000000 == 0) {
            std::cerr << "\r\rprocessed " << stop << " positions";
        }
        // We always update the end position
        ++stop;
    }
    if (start < tlen) {
        if (currentKmer.length() == k and
            currentKmer.find_first_of('$') != std::string::npos) {
            mer = rapmap::utils::my_mer(currentKmer);
            khash[mer.get_bits(0, 2*k)] = {start, stop};
        }
    }
    std::cerr << "\nkhash had " << khash.size() << " keys\n";
    std::ofstream hashStream(outputDir + "hash.bin", std::ios::binary);
    {
        ScopedTimer timer;
        std::cerr << "saving hash to disk . . . ";
        cereal::BinaryOutputArchive hashArchive(hashStream);
        hashArchive(k);
        khash.serialize(google::dense_hash_map<uint64_t,
                        rapmap::utils::SAInterval,
                        rapmap::utils::KmerKeyHasher>::NopointerSerializer(), &hashStream);
        //hashArchive(khash);
        std::cerr << "done\n";
    }
    hashStream.close();


    std::string indexVersion = "q0";
    IndexHeader header(IndexType::QUASI, indexVersion, true, k);
    // Finally (since everything presumably succeeded) write the header
    std::ofstream headerStream(outputDir + "header.json");
    {
	cereal::JSONOutputArchive archive(headerStream);
	archive(header);
    }
    headerStream.close();

}
Esempio n. 22
0
HANDLE init_tap()
{
  HANDLE hTAP32 = INVALID_HANDLE_VALUE;
  HKEY key;
  int enum_index, retry_attempts;
  char devid[1024], devname[1024];
  long len;
  ULONG status = TRUE;
  HKEY interface_key;
  char path[1024];
  struct sockaddr_in dns;
  char *addr_string;
  MIB_IPFORWARDROW route;
  DWORD dw;
  /* LPVOID lpMsgBuf; */ /* debug */

  printf("init_tap()\n");

  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0,
                   KEY_READ, &key))
    {
      printf("Unable to read registry:\n");
      return(NULL);
    }

  /* find the adapter with .tap suffix */
  for (enum_index = 0;; enum_index++)
    {
      len = sizeof(devid);
      if (RegEnumKeyEx(key, enum_index, devid, &len,
                       0, 0, 0, NULL) != ERROR_SUCCESS)
        {
          RegCloseKey(key);
          /* we've hit the end of the network connections list */
          printf("init_tap(): Couldn't find TAP-Win32 adapter.\n");
          return(NULL);
        }

      retry_attempts = 0;
init_tap_create_file_retry:
      sprintf(devname, "\\\\.\\Global\\%s.tap", devid);
      hTAP32 = CreateFile(devname,
                          GENERIC_WRITE | GENERIC_READ,
                          0,
                          0,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_SYSTEM,
                          0);

      dw = GetLastError();
      /* This is the most common error. We are trying to open
       * this device as a TAP but it is not a TAP-Win32 device,
       * so continue with the search.
       */
      if (dw == ERROR_FILE_NOT_FOUND)
        {
          continue;
          /* This error "A device attached to the system is not
           * functioning." occurs when we've found the TAP but
           * cannot open it. This could be restarting the HIP
           * service, so try again.
           */
        }
      else if (dw == ERROR_GEN_FAILURE)
        {
          if (retry_attempts < 3)
            {
              /* pause 400ms for device to become ready */
              Sleep(400);
              retry_attempts++;
              printf("Retrying open on TAP device...\n");
              goto init_tap_create_file_retry;
            }
        }

      /* debug
       *  FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|
       *               FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw,
       *               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
       *               (LPTSTR) &lpMsgBuf, 0, NULL);
       *
       *  printf("DEBUG: devname %s error %d: %s\n",
       *       devname, dw, lpMsgBuf);
       *  LocalFree(lpMsgBuf); */

      /* dw == NO_ERROR */
      if (hTAP32 != INVALID_HANDLE_VALUE)
        {
          RegCloseKey(key);
          CloseHandle(hTAP32);
          break;
        }
    }

  /* Get the MAC address of the TAP-Win32
   * which is of the form 00:FF:{GID}
   */
  g_tap_mac = gid_to_mac(devid + 1);

  if (check_and_set_tun_address(devid, 1) < 0)
    {
      printf("TAP-Win32 setup failed.\n");
      return(NULL);
    }

  /* Open TAP-Win32 device */
  hTAP32 = CreateFile(devname, GENERIC_WRITE | GENERIC_READ, 0, 0,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
  if (hTAP32 == INVALID_HANDLE_VALUE)
    {
      printf("Could not open Windows tap device\n");
      return(NULL);
    }

  /* set TAP-32 status to connected */
  if (!DeviceIoControl (hTAP32, TAP_IOCTL_SET_MEDIA_STATUS,
                        &status, sizeof (status),
                        &status, sizeof (status), &len, NULL))
    {
      printf("failed to set TAP-Win32 status as 'connected'.\n");
      return(NULL);
    }

  Sleep(10);

  /* set NameServer address on TAP-Win32 adapter to 1.x.x.x */
  sprintf (path, "%s\\%s", REG_INTERFACES_KEY, devid);
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
                   KEY_WRITE, &interface_key) != ERROR_SUCCESS)
    {
      printf("Error opening registry key: %s", path);
      return(NULL);
    }

  memset(&dns, 0, sizeof(struct sockaddr_in));
  dns.sin_family = AF_INET;
  if (is_dns_thread_disabled())
    {
      memset(SA2IP(&dns), 0, 4);
    }
  else
    {
      get_preferred_lsi(SA(&dns));
    }
  addr_string = inet_ntoa(dns.sin_addr);
  if (RegSetValueEx(interface_key, "NameServer", 0, REG_SZ,
                    addr_string, strlen(addr_string)) != ERROR_SUCCESS)
    {
      printf("Changing TAP-Win32 adapter's NameServer failed\n");
      return(NULL);
    }
  RegCloseKey(interface_key);

  /* also add route for 1.0.0.0/8 to TAP-Win32 */
  memset(&route, 0, sizeof(route));
  route.dwForwardDest = htonl(0x01000000L);
  route.dwForwardMask = htonl(0xFF000000L);
  CreateIpForwardEntry(&route);

  /* add 2001:10::/28 HIT to TAP-Win32 */
  /* TODO */
  /* IPv6 may not be installed */
  /* equivalent of netsh interface ipv6 add address 2001:007x:xxxx ... */
  /* */

  return(hTAP32);
}
Esempio n. 23
0
/** Sends a request to a RADIUS server and waits for the reply
 *
 * @param rh a handle to parsed configuration
 * @param ctx if non-NULL it will contain the context of sent request; It must be released using rc_aaa_ctx_free().
 * @param data a pointer to a SEND_DATA structure
 * @param msg must be an array of %PW_MAX_MSG_SIZE or NULL; will contain the concatenation of
 *	any %PW_REPLY_MESSAGE received.
 * @param type must be %AUTH or %ACCT
 * @return OK_RC (0) on success, TIMEOUT_RC on timeout REJECT_RC on acess reject, or negative
 *	on failure as return value.
 */
int rc_send_server_ctx(rc_handle * rh, RC_AAA_CTX ** ctx, SEND_DATA * data,
		       char *msg, rc_type type)
{
	int sockfd = -1;
	AUTH_HDR *auth, *recv_auth;
	char *server_name, *p;	/* Name of server to query */
	struct sockaddr_storage our_sockaddr;
	struct addrinfo *auth_addr = NULL;
	socklen_t salen;
	int result = 0;
	int total_length;
	int length, pos;
	int retry_max;
	const rc_sockets_override *sfuncs;
	unsigned discover_local_ip;
	size_t secretlen;
	char secret[MAX_SECRET_LENGTH + 1];
	unsigned char vector[AUTH_VECTOR_LEN];
	uint8_t recv_buffer[BUFFER_LEN];
	uint8_t send_buffer[BUFFER_LEN];
	uint8_t *attr;
	int retries;
	VALUE_PAIR *vp;
	struct pollfd pfd;
	double start_time, timeout;
	struct sockaddr_storage *ss_set = NULL;
	char *server_type = "auth";

	server_name = data->server;
	if (server_name == NULL || server_name[0] == '\0')
		return ERROR_RC;

	if ((vp = rc_avpair_get(data->send_pairs, PW_SERVICE_TYPE, 0)) &&
	    (vp->lvalue == PW_ADMINISTRATIVE)) {
		strcpy(secret, MGMT_POLL_SECRET);
		auth_addr =
		    rc_getaddrinfo(server_name,
				   type == AUTH ? PW_AI_AUTH : PW_AI_ACCT);
		if (auth_addr == NULL)
			return ERROR_RC;
	} else {
		if (data->secret != NULL) {
			strlcpy(secret, data->secret, MAX_SECRET_LENGTH);
		}
		/*
		   else
		   {
		 */
		if (rc_find_server_addr
		    (rh, server_name, &auth_addr, secret, type) != 0) {
			rc_log(LOG_ERR,
			       "rc_send_server: unable to find server: %s",
			       server_name);
			return ERROR_RC;
		}
		/*} */
	}

	sfuncs = &rh->so;

	if (sfuncs->static_secret) {
		/* any static secret set in sfuncs overrides the configured */
		strlcpy(secret, sfuncs->static_secret,
			MAX_SECRET_LENGTH);
	}

	if (sfuncs->lock) {
		if (sfuncs->lock(sfuncs->ptr) != 0) {
			rc_log(LOG_ERR, "%s: lock error", __func__);
			return ERROR_RC;
		}
	}

	rc_own_bind_addr(rh, &our_sockaddr);
	discover_local_ip = 0;
	if (our_sockaddr.ss_family == AF_INET) {
		if (((struct sockaddr_in *)(&our_sockaddr))->sin_addr.s_addr ==
		    INADDR_ANY) {
			discover_local_ip = 1;
		}
	}

	DEBUG(LOG_ERR, "DEBUG: rc_send_server: creating socket to: %s",
	      server_name);
	if (discover_local_ip) {
		result = rc_get_srcaddr(SA(&our_sockaddr), auth_addr->ai_addr);
		if (result != 0) {
			memset(secret, '\0', sizeof(secret));
			rc_log(LOG_ERR,
			       "rc_send_server: cannot figure our own address");
			result = ERROR_RC;
			goto cleanup;
		}
	}

	if (sfuncs->get_fd) {
		sockfd = sfuncs->get_fd(sfuncs->ptr, SA(&our_sockaddr));
		if (sockfd < 0) {
			memset(secret, '\0', sizeof(secret));
			rc_log(LOG_ERR, "rc_send_server: socket: %s",
			       strerror(errno));
			result = ERROR_RC;
			goto cleanup;
		}
	}

	retry_max = data->retries;	/* Max. numbers to try for reply */
	retries = 0;		/* Init retry cnt for blocking call */

	if (data->svc_port) {
		if (our_sockaddr.ss_family == AF_INET)
			((struct sockaddr_in *)auth_addr->ai_addr)->sin_port =
			    htons((unsigned short)data->svc_port);
		else
			((struct sockaddr_in6 *)auth_addr->ai_addr)->sin6_port =
			    htons((unsigned short)data->svc_port);
	}

	/*
	 * Fill in NAS-IP-Address (if needed)
	 */
	if (rh->nas_addr_set) {
		rc_avpair_remove(&(data->send_pairs), PW_NAS_IP_ADDRESS, 0);
		rc_avpair_remove(&(data->send_pairs), PW_NAS_IPV6_ADDRESS, 0);

		ss_set = &rh->nas_addr;
	} else if (rc_avpair_get(data->send_pairs, PW_NAS_IP_ADDRESS, 0) == NULL &&
	    	   rc_avpair_get(data->send_pairs, PW_NAS_IPV6_ADDRESS, 0) == NULL) {

	    	ss_set = &our_sockaddr;
	}

	if (ss_set) {
		if (ss_set->ss_family == AF_INET) {
			uint32_t ip;
			ip = *((uint32_t
				*) (&((struct sockaddr_in *)ss_set)->
				    sin_addr));
			ip = ntohl(ip);

			rc_avpair_add(rh, &(data->send_pairs),
				      PW_NAS_IP_ADDRESS, &ip, 0, 0);
		} else {
			void *p;
			p = &((struct sockaddr_in6 *)ss_set)->sin6_addr;

			rc_avpair_add(rh, &(data->send_pairs),
				      PW_NAS_IPV6_ADDRESS, p, 16, 0);
		}
	}

	/*
	 * Fill in NAS-Identifier (if needed)
	 */
	p = rc_conf_str(rh, "nas-identifier");
	if (p != NULL) {
		rc_avpair_remove(&(data->send_pairs), PW_NAS_IDENTIFIER, 0);
		rc_avpair_add(rh, &(data->send_pairs),
			      PW_NAS_IDENTIFIER, p, -1, 0);
	}

	/* Build a request */
	auth = (AUTH_HDR *) send_buffer;
	auth->code = data->code;
	auth->id = data->seq_nbr;

	if (data->code == PW_ACCOUNTING_REQUEST) {
		server_type = "acct";
		total_length =
		    rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;

		auth->length = htons((unsigned short)total_length);

		memset((char *)auth->vector, 0, AUTH_VECTOR_LEN);
		secretlen = strlen(secret);
		memcpy((char *)auth + total_length, secret, secretlen);
		rc_md5_calc(vector, (unsigned char *)auth,
			    total_length + secretlen);
		memcpy((char *)auth->vector, (char *)vector, AUTH_VECTOR_LEN);
	} else {
		rc_random_vector(vector);
		memcpy((char *)auth->vector, (char *)vector, AUTH_VECTOR_LEN);

		total_length =
		    rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;

		auth->length = htons((unsigned short)total_length);
	}

	if (radcli_debug) {
		char our_addr_txt[50] = "";	/* hold a text IP */
		char auth_addr_txt[50] = "";	/* hold a text IP */

		getnameinfo(SA(&our_sockaddr), SS_LEN(&our_sockaddr), NULL, 0,
			    our_addr_txt, sizeof(our_addr_txt), NI_NUMERICHOST);
		getnameinfo(auth_addr->ai_addr, auth_addr->ai_addrlen, NULL, 0,
			    auth_addr_txt, sizeof(auth_addr_txt),
			    NI_NUMERICHOST);

		DEBUG(LOG_ERR,
		      "DEBUG: timeout=%d retries=%d local %s : 0, remote %s : %u\n",
		      data->timeout, retry_max, our_addr_txt, auth_addr_txt,
		      data->svc_port);
	}

	for (;;) {
		do {
			result =
			    sfuncs->sendto(sfuncs->ptr, sockfd, (char *)auth,
					   (unsigned int)total_length, (int)0,
					   SA(auth_addr->ai_addr),
					   auth_addr->ai_addrlen);
		} while (result == -1 && errno == EINTR);
		if (result == -1) {
			rc_log(LOG_ERR, "%s: socket: %s", __FUNCTION__,
			       strerror(errno));
			result = ERROR_RC;
			goto cleanup;
		}

		pfd.fd = sockfd;
		pfd.events = POLLIN;
		pfd.revents = 0;
		start_time = rc_getmtime();
		for (timeout = data->timeout; timeout > 0;
		     timeout -= rc_getmtime() - start_time) {
			result = poll(&pfd, 1, timeout * 1000);
			if (result != -1 || errno != EINTR)
				break;
		}

		if (result == -1) {
			rc_log(LOG_ERR, "rc_send_server: poll: %s",
			       strerror(errno));
			memset(secret, '\0', sizeof(secret));
			SCLOSE(sockfd);
			result = ERROR_RC;
			goto cleanup;
		}

		if (result == 1 && (pfd.revents & POLLIN) != 0) {
			salen = auth_addr->ai_addrlen;
			do {
				length = sfuncs->recvfrom(sfuncs->ptr, sockfd,
							  (char *)recv_buffer,
							  (int)
							  sizeof(recv_buffer),
							  (int)0,
							  SA(auth_addr->
							     ai_addr), &salen);
			} while (length == -1 && errno == EINTR);

			if (length <= 0) {
				int e = errno;
				rc_log(LOG_ERR,
				       "rc_send_server: recvfrom: %s:%d: %s",
				       server_name, data->svc_port,
				       strerror(e));
				if (length == -1 && (e == EAGAIN || e == EINTR))
					continue;
				SCLOSE(sockfd);
				memset(secret, '\0', sizeof(secret));
				result = ERROR_RC;
				goto cleanup;
			}

			recv_auth = (AUTH_HDR *) recv_buffer;

			if (length < AUTH_HDR_LEN
			    || length < ntohs(recv_auth->length)) {
				rc_log(LOG_ERR,
				       "rc_send_server: recvfrom: %s:%d: reply is too short",
				       server_name, data->svc_port);
				SCLOSE(sockfd);
				memset(secret, '\0', sizeof(secret));
				result = ERROR_RC;
				goto cleanup;
			}

			result =
			    rc_check_reply(recv_auth, BUFFER_LEN, secret,
					   vector, data->seq_nbr);
			if (result != BADRESPID_RC) {
				/* if a message that doesn't match our ID was received, then ignore
				 * it, and try to receive more, until timeout. That is because in
				 * DTLS the channel is shared, and we may receive duplicates or
				 * out-of-order packets. */
				break;
			}
		}

		/*
		 * Timed out waiting for response.  Retry "retry_max" times
		 * before giving up.  If retry_max = 0, don't retry at all.
		 */
		if (retries++ >= retry_max) {
			char radius_server_ip[128];
			struct sockaddr_in *si =
			    (struct sockaddr_in *)auth_addr->ai_addr;
			inet_ntop(auth_addr->ai_family, &si->sin_addr,
				  radius_server_ip, sizeof(radius_server_ip));
			rc_log(LOG_ERR,
			       "rc_send_server: no reply from RADIUS %s server %s:%u",
			       server_type, radius_server_ip, data->svc_port);
			SCLOSE(sockfd);
			memset(secret, '\0', sizeof(secret));
			result = TIMEOUT_RC;
			goto cleanup;
		}
	}

	/*
	 *      If UDP is larger than RADIUS, shorten it to RADIUS.
	 */
	if (length > ntohs(recv_auth->length))
		length = ntohs(recv_auth->length);

	/*
	 *      Verify that it's a valid RADIUS packet before doing ANYTHING with it.
	 */
	attr = recv_buffer + AUTH_HDR_LEN;
	while (attr < (recv_buffer + length)) {
		if (attr[0] == 0) {
			rc_log(LOG_ERR,
			       "rc_send_server: recvfrom: %s:%d: attribute zero is invalid",
			       server_name, data->svc_port);
			SCLOSE(sockfd);
			memset(secret, '\0', sizeof(secret));
			result = ERROR_RC;
			goto cleanup;
		}

		if (attr[1] < 2) {
			rc_log(LOG_ERR,
			       "rc_send_server: recvfrom: %s:%d: attribute length is too small",
			       server_name, data->svc_port);
			SCLOSE(sockfd);
			memset(secret, '\0', sizeof(secret));
			result = ERROR_RC;
			goto cleanup;
		}

		if ((attr + attr[1]) > (recv_buffer + length)) {
			rc_log(LOG_ERR,
			       "rc_send_server: recvfrom: %s:%d: attribute overflows the packet",
			       server_name, data->svc_port);
			SCLOSE(sockfd);
			memset(secret, '\0', sizeof(secret));
			result = ERROR_RC;
			goto cleanup;
		}

		attr += attr[1];
	}

	length = ntohs(recv_auth->length) - AUTH_HDR_LEN;
	if (length > 0) {
		data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data,
						    length, 0);
	} else {
		data->receive_pairs = NULL;
	}

	SCLOSE(sockfd);
	result = populate_ctx(ctx, secret, vector);
	if (result != OK_RC) {
		memset(secret, '\0', sizeof(secret));
		goto cleanup;
	}

	memset(secret, '\0', sizeof(secret));

	if (msg) {
		*msg = '\0';
		pos = 0;
		vp = data->receive_pairs;
		while (vp) {
			if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0))) {
				strappend(msg, PW_MAX_MSG_SIZE, &pos,
					  vp->strvalue);
				strappend(msg, PW_MAX_MSG_SIZE, &pos, "\n");
				vp = vp->next;
			}
		}
	}

	if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
	    (recv_auth->code == PW_PASSWORD_ACK) ||
	    (recv_auth->code == PW_ACCOUNTING_RESPONSE)) {
		result = OK_RC;
	} else if ((recv_auth->code == PW_ACCESS_REJECT) ||
		   (recv_auth->code == PW_PASSWORD_REJECT)) {
		result = REJECT_RC;
	} else {
		rc_log(LOG_ERR, "rc_send_server: received RADIUS server response neither ACCEPT nor REJECT, invalid");
		result = BADRESP_RC;
	}

 cleanup:
	if (auth_addr)
		freeaddrinfo(auth_addr);

	if (sfuncs->unlock) {
		if (sfuncs->unlock(sfuncs->ptr) != 0) {
			rc_log(LOG_ERR, "%s: unlock error", __func__);
		}
	}

	return result;
}
Esempio n. 24
0
/*
 * Check the static IP address for the TAP device and set it if necessary.
 */
int check_and_set_tun_address(char *devid, int do_msgbox)
{
  HKEY interface_key, key;
  DWORD dwVal, dwKeyType, dwBufLen;
  char path[1024], value[512], sLSI[17];
  int enum_index, need_setup = 0;
  long len;
  struct sockaddr_storage lsi;

  /*
   * Get the preferred LSI from hipd, from XML file
   */
  memset(&lsi, 0, sizeof(struct sockaddr_storage));
  lsi.ss_family = AF_INET;
  get_preferred_lsi(SA(&lsi));
  memset(sLSI, 0, sizeof(sLSI));       /* LSI + "\0\0" */
  sprintf(sLSI, "%u.%u.%u.%u", NIPQUAD(LSI4(&lsi)));
  if (LSI4(&lsi) == 0)
    {
      printf("Unable to determine preferred LSI.\n");
      return(-1);
    }
  else
    {
      printf("Using LSI of %s for TAP address.\n", sLSI);
    }

  /*
   * Check registry values for
   * IPAddress, SubnetMask, and EnableDHCP
   */
  sprintf (path, "%s\\%s", REG_INTERFACES_KEY, devid);
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &interface_key)
      != ERROR_SUCCESS)
    {
      printf("Error opening registry key: %s", path);
      return(-1);
    }
  dwBufLen = sizeof(value);
  if (RegQueryValueEx(interface_key, "IPAddress", NULL, &dwKeyType,
                      value, &dwBufLen) != ERROR_SUCCESS)
    {
      printf("Unable to read IP address, doing setup.\n");
      need_setup = 1;
    }
  if ((dwKeyType != REG_MULTI_SZ) ||
      (strncmp(value, sLSI, strlen(sLSI) + 2) != 0))
    {
      need_setup = 1;
    }
  dwBufLen = sizeof(value);
  if (RegQueryValueEx(interface_key, "SubnetMask", NULL, &dwKeyType,
                      value, &dwBufLen) != ERROR_SUCCESS)
    {
      printf("Unable to read network mask, doing setup.\n");
      need_setup = 1;
    }
  if ((dwKeyType != REG_MULTI_SZ) ||
      (strncmp(value, "255.0.0.0\0\0", 11) != 0))
    {
      need_setup = 1;
    }
  dwBufLen = sizeof(dwVal);
  if (RegQueryValueEx(interface_key, "EnableDHCP", NULL, &dwKeyType,
                      (LPBYTE)&dwVal, &dwBufLen) != ERROR_SUCCESS)
    {
      printf("Unable to read DHCP setting, doing setup.\n");
      need_setup = 1;
    }
  if ((dwKeyType != REG_DWORD) || (dwVal != 0x0))
    {
      need_setup = 1;
    }

  RegCloseKey(interface_key);
  if (!need_setup)
    {
      return(0);
    }

  /* Used to prompt user for setup, but now it is important that
   * the TAP address be set to the preferred LSI.
   */
  printf("Configuring the TAP-Win32 adapter.\n");
#if 0
  if (do_msgbox && (MessageBox(NULL,
                               "Your TAP-Win32 interface needs to be setup to run HIP for Windows, shall I do that for you?",
                               "HIP for Windows",
                               MB_YESNO | MB_ICONQUESTION) != IDYES))
    {
      return(-1);
    }
#endif

  /*
   * Write the new values to the registry
   */
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
                   KEY_WRITE, &interface_key) != ERROR_SUCCESS)
    {
      printf("Error opening registry key: %s", path);
      return(-1);
    }
  if (RegSetValueEx(interface_key, "IPAddress", 0, REG_MULTI_SZ,
                    sLSI, strlen(sLSI) + 2) != ERROR_SUCCESS)
    {
      printf("Changing TAP-Win32 adapter's IP address failed\n");
      return(-1);
    }
  if (RegSetValueEx(interface_key, "SubnetMask", 0, REG_MULTI_SZ,
                    "255.0.0.0\0\0",
                    strlen("255.0.0.0") + 2) != ERROR_SUCCESS)
    {
      printf("Changing TAP-Win32 adapter's IP mask failed\n");
      return(-1);
    }
  dwVal = 0x0;
  if (RegSetValueEx(interface_key, "EnableDHCP", 0, REG_DWORD,
                    (LPBYTE)&dwVal, sizeof(dwVal)) != ERROR_SUCCESS)
    {
      printf("Changing TAP-Win32 adapter's DHCP setting failed\n");
      return(-1);
    }
  RegCloseKey(interface_key);

  /*
   * Set TAP MTU to 1400
   */
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0,
                   KEY_READ, &key) != ERROR_SUCCESS)
    {
      printf("Error opening registry key: %s", ADAPTER_KEY);
      return(-1);
    }
  /* find the adapter with TAP_COMPONENT_ID (tap0801) */
  for (enum_index = 0;; enum_index++)
    {
      len = sizeof(value);
      if (RegEnumKeyEx(key, enum_index, value, &len,
                       0, 0, 0, NULL) != ERROR_SUCCESS)
        {
          RegCloseKey(key);
          return(0);               /* silently exit if not found */
        }
      sprintf(path, "%s\\%s", ADAPTER_KEY, value);
      if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ,
                       &interface_key) != ERROR_SUCCESS)
        {
          continue;
        }
      dwBufLen = sizeof(value);
      if (RegQueryValueEx(interface_key, "ComponentId", NULL,
                          &dwKeyType, value,
                          &dwBufLen) != ERROR_SUCCESS)
        {
          RegCloseKey(interface_key);
          continue;
        }
      RegCloseKey(interface_key);
      if ((dwKeyType != REG_SZ) ||
          (strncmp(value, TAP_COMPONENT_ID,
                   strlen(TAP_COMPONENT_ID)) != 0))
        {
          continue;
        }
      break;
    }

  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_WRITE,
                   &interface_key) != ERROR_SUCCESS)
    {
      printf("Unable to set TAP MTU.\n");
      return(0);           /* non-fatal */
    }
  if (RegSetValueEx(interface_key, "MTU", 0, REG_SZ,
                    "1400", strlen("1400")) != ERROR_SUCCESS)
    {
      printf("Changing TAP-Win32 MTU failed.\n");
    }
  RegCloseKey(interface_key);
  return(0);
}
Esempio n. 25
0
/*
 * \fn hip_dht_update_my_entries()
 *
 * \param flags		integer used to signal init and cleanup of DHT
 *                      0 = normal update, 1 = startup, 2 = shutdown
 *
 * Publish (HIT, IP) and (name, HIT) combinations to a DHT,
 * to support both type of lookups. This is called upon startup and periodically
 * after the preferred address has been selected. This maintains the timed
 * DHT records, removes old values, and publishes new records.
 */
void hip_dht_update_my_entries(int flags)
{
  struct sockaddr_storage ss_server;
  struct sockaddr *addr, *server = (struct sockaddr*)&ss_server;
  sockaddr_list *l;
  struct dht_val *v;
#ifndef __WIN32__
  pthread_attr_t attr;
  pthread_t thr;
#endif
  /* initialize DHT structures */
  if (flags == 1)
    {
      pthread_mutex_init(&dht_vals_lock, NULL);
      dht_vals = NULL;
      /* pass-through to publishing... */
      /* deinitialize */
    }
  else if (flags == 2)
    {
      /* remove all values from the DHT (during shutdown) */
      pthread_mutex_lock(&dht_vals_lock);
      v = dht_vals;
      while (dht_vals)
        {
          hip_xmlrpc_rm(v);               /* remove the value from the DHT */
          v = dht_vals->next;
          free(dht_vals);
          dht_vals = v;
        }
      pthread_mutex_unlock(&dht_vals_lock);
      return;
    }

  if (hip_dht_select_server(server) < 0)
    {
      return;           /* prevents unneccessary thread creation */

    }
  /* only publish our preferred address */
  addr = NULL;
  for (l = my_addr_head; l; l = l->next)
    {
      if (IS_LSI(&l->addr))             /* skip any LSIs */
        {
          continue;
        }
      if (!l->preferred)
        {
          continue;
        }
      addr = SA(&l->addr);
      break;
    }
  if (!addr)         /* no preferred address */
    {
      return;
    }

#ifdef __WIN32__
  _beginthread(publish_my_hits_thread, 0, (void *)addr);
#else
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  pthread_create(&thr, &attr, publish_my_hits_thread, addr);
#endif /* __WIN32__ */
  return;
}
Esempio n. 26
0
File: child.c Progetto: aosm/xinetd
/*
 * This function is invoked in a forked process to run a server. 
 * If the service is internal the appropriate function is invoked
 * otherwise the server program is exec'ed.
 * This function also logs the remote user id if appropriate
 */
void child_process( struct server *serp )
{
   struct service          *sp  = SERVER_SERVICE( serp ) ;
   connection_s            *cp  = SERVER_CONNECTION( serp ) ;
   struct service_config   *scp = SVC_CONF( sp ) ;
   const char              *func = "child_process" ;

   signal_default_state();

   if ((signals_pending[0] >= 0 && Sclose(signals_pending[0])) ||
       (signals_pending[1] >= 0 && Sclose(signals_pending[1])))
   {
      msg(LOG_ERR, func, "Failed to close the signal pipe: %m");
      _exit(1);
   }
   signals_pending[0] = -1;
   signals_pending[1] = -1;

   Sclose(0);
   Sclose(1);
   Sclose(2);


#ifdef DEBUG_SERVER
   if ( debug.on )
   {
      msg( LOG_DEBUG, func, "Process %d is sleeping", getpid() ) ;
      sleep( 10 ) ;
   }
#endif

   if ( ! SC_IS_INTERCEPTED( scp ) )
   {
      set_credentials( scp ) ;
      if ( SC_SPECIFIED( scp, A_NICE ) )
         (void) nice( SC_NICE( scp ) ) ;
   }

   if ( svc_child_access_control(sp, cp) != OK )
      exit(0);

   if ( SERVER_LOGUSER( serp ) )
   {
      unsigned   timeout ;
      idresult_e result ;
      
      /*
       * We use LOGUSER_SUCCESS_TIMEOUT unless the service requires
       * identification, in which case we use an infinite timeout
       */
      timeout = SC_MUST_IDENTIFY( scp ) ? 0 : LOGUSER_SUCCESS_TIMEOUT ;
      result = log_remote_user( serp, timeout ) ;

      if ( result != IDR_OK && SC_MUST_IDENTIFY( scp ) )
      {
         svc_logprint( sp, NOID_ENTRY, "%s %s",
                  conn_addrstr( SERVER_CONNECTION( serp ) ),
                     idresult_explain( result ) ) ;
         _exit( 0 ) ;
      }
   }

#ifdef HAVE_SESSIONCREATE
   if ( scp->sc_sessioncreate == YES ) 
   {
      if ( SessionCreate(0, sessionHasTTY|sessionIsRemote) != noErr )
         svc_logprint( sp, "SessionCreate", "SessionCreate() failed!" );
   }
#endif

   /* this is where the server gets executed  -bbraun */
   if ( ! SC_IS_INTERNAL( scp ) )
   {
      if( scp->sc_redir_addr != NULL )
      {
         redir_handler( serp );
      }
      else
      {
#if defined(HAVE_SETENV)
         char buff[1024];

         strx_sprint(buff, sizeof(buff)-1, "REMOTE_HOST=%s", conn_addrstr(cp));
         if( env_addstr(SC_ENV(scp)->env_handle, buff) != ENV_OK ) {
            msg( LOG_ERR, func, "Error adding REMOTE_HOST variable for %s: %m", SC_NAME(scp) );
            _exit( 1 ) ;
         }
#endif
         exec_server( serp ) ;
      }
   }
   else
   {
      char name[ 180 ] ;
      /*
       * We don't bother to disassociate from the controlling terminal
       *   (we have a controlling terminal only if debug.on is TRUE)
       *
       * Also, for interceptor processes, we give them the name:
       *            <program_name> <service-id> interceptor
       */
      if ( SC_IS_INTERCEPTED( scp ) )
         strx_print( INT_NULL, name, sizeof( name ) - 1,
                           "%s %s interceptor", program_name, SC_ID( scp ) ) ;
      else
      {
         int namelen = sizeof( name ) - 1 ;      /* leave space for the NUL */
         char host[NI_MAXHOST];
         size_t hostlen = NI_MAXHOST;
         socklen_t addrlen = 0;
         union xsockaddr *sinp = CONN_XADDRESS(SERVER_CONNECTION(serp));
         int len;

         if( sinp == NULL )
            exit(0);

         if( SC_IPV6(scp) ) addrlen = sizeof(struct sockaddr_in6);
         else if( SC_IPV4(scp) ) addrlen = sizeof(struct sockaddr_in);

         len = strx_nprint(name, namelen, "(%s service) %s", program_name,
            SC_ID( scp ) ) ;

         if( getnameinfo( SA(sinp), addrlen, host, hostlen, NULL, 0, 0) != 0 )
               strcpy(host, "unknown");

         if ( SC_IPV6(scp) && SC_ACCEPTS_CONNECTIONS( scp ) && 
               !IN6_IS_ADDR_UNSPECIFIED(&sinp->sa_in6.sin6_addr) )
            strx_print( INT_NULL, &name[ len ], namelen - len, " %s" , host ) ;
         if ( SC_IPV4(scp) && SC_ACCEPTS_CONNECTIONS( scp ) )
            strx_print( INT_NULL, &name[ len ], namelen - len, " %s", host ) ;
      }
      rename_process( name ) ;
      SVC_INTERNAL( sp, serp ) ;
   }
   _exit( 0 ) ;
   /* NOTREACHED */
}
Esempio n. 27
0
/*
 * \fn hip_xmlrpc_getput()
 *
 * \param mode		determines get or put, app, retry on/off
 *		         If retry is off only one attempt should be made,
 *                       on means the connect() should keep retrying
 * \param app		string to use in the XML RPC application field
 * \param server	server address and port to connect to
 * \param key           DHT key used for get or put
 * \param key_len	length of DHT key in bytes
 * \param value		DHT value used for put, ptr for storing value for get
 * \param value_len	ptr to length of value buffer, length of get is returned
 * \param secret	secret value used to make put removable
 * \param secret_len	length of secret value
 * \param ttl		time to live in seconds
 *
 * \brief Perform the XML RPC GET, PUT, and RM operations.
 */
int hip_xmlrpc_getput(int mode, char *app, struct sockaddr *server,
                      char *key, int key_len, char *value, int *value_len,
                      char *secret, int secret_len, int ttl)
{
  xmlDocPtr doc = NULL;
  xmlNodePtr root_node = NULL, node;
  int len = 0, s, retval = 0;
  char buff[2048], oper[14];
  unsigned char key64[2 * DHT_KEY_SIZE], val64[2 * DHT_VAL_SIZE];
  unsigned char tmp[2 * DHT_VAL_SIZE], *xmlbuff = NULL;
  fd_set read_fdset;
  struct timeval timeout, now;
  char *p;
  unsigned int retry_attempts = 0;
  struct sockaddr_in src_addr;
  struct dht_val *dv, rm;
  SHA_CTX c;
  __u8 secret_hash[SHA_DIGEST_LENGTH], value_hash[SHA_DIGEST_LENGTH];
  int rm_ttl = 0, value_hash_len;

  int retry = ((mode & 0x00F0) == XMLRPC_MODE_RETRY_ON);

  if ((key_len > (2 * DHT_KEY_SIZE)) ||
      (*value_len > (2 * DHT_VAL_SIZE)))
    {
      return(-1);
    }

  /*
   * support for removable puts
   */
  memset(&rm, 0, sizeof(struct dht_val));
  if ((mode & 0x000F) == XMLRPC_MODE_PUT)
    {
      /*
       * produce hashes of the secret and the value, for later removal
       */
      SHA1_Init(&c);
      SHA1_Update(&c, value, *value_len);
      SHA1_Final(value_hash, &c);
      SHA1_Init(&c);
      SHA1_Update(&c, secret, secret_len);
      SHA1_Final(secret_hash, &c);

      /*
       * check if we already published a record with this key; record
       * this new secret value and value_hash
       */
      pthread_mutex_lock(&dht_vals_lock);
      gettimeofday(&now, NULL);
      dv = lookup_dht_val(key);
      if (dv)
        {
          /* save old secret so we can remove it later below */
          memcpy(&rm, &dv, sizeof(struct dht_val));
          /* any time left for removing the old record? */
          rm_ttl = TDIFF(rm.expire_time, now);
        }
      else
        {
          dv = insert_dht_val(key);
        }
      strncpy(dv->app, app, sizeof(dv->app));
      dv->value_hash_len = SHA_DIGEST_LENGTH;
      memcpy(dv->value_hash, value_hash, SHA_DIGEST_LENGTH);
      dv->secret_len = secret_len;
      memcpy(dv->secret, secret, secret_len);
      dv->expire_time.tv_usec = now.tv_usec;
      dv->expire_time.tv_sec = now.tv_sec + ttl;
      pthread_mutex_unlock(&dht_vals_lock);
    }

  switch (mode & 0x000F)
    {
    case XMLRPC_MODE_PUT:
      sprintf(oper, "put_removable");
      break;
    case XMLRPC_MODE_GET:
      sprintf(oper, "get");
      break;
    case XMLRPC_MODE_RM:
      sprintf(oper, "rm");
      break;
    default:
      log_(WARN, "Invalid XMLRPC mode given to DHT.\n");
      return(-1);
    }

  /*
   * create a new XML document
   */
  doc = xmlNewDoc(BAD_CAST "1.0");
  root_node = xmlNewNode(NULL, BAD_CAST "methodCall");
  xmlDocSetRootElement(doc, root_node);
  node = xmlNewChild(root_node, NULL, BAD_CAST "methodName",
                     BAD_CAST oper);
  node = xmlNewChild(root_node, NULL, BAD_CAST "params", NULL);
  memset(tmp, 0, sizeof(tmp));
  memcpy(tmp, key, key_len);
  EVP_EncodeBlock(key64, tmp, key_len);
  xml_new_param(node, "base64", (char *)key64);                 /* key */
  /* log_(NORM, "Doing %s using key(%d)=",
   *    ((mode & 0x000F)==XMLRPC_MODE_PUT) ? "PUT":"GET", key_len);
   *  print_hex(key, key_len);
   *  log_(NORM, " [%s]\n", key64); // */
  switch (mode & 0x000F)
    {
    case XMLRPC_MODE_PUT:
      memset(tmp, 0, sizeof(tmp));
      memcpy(tmp, value, *value_len);
      EVP_EncodeBlock(val64, tmp, *value_len);
      xml_new_param(node, "base64", (char *)val64);             /* value */
      xml_new_param(node, "string", "SHA");                     /* hash type */
      memset(tmp, 0, sizeof(tmp));
      memcpy(tmp, secret_hash, SHA_DIGEST_LENGTH);
      EVP_EncodeBlock(val64, tmp, SHA_DIGEST_LENGTH);
      xml_new_param(node, "base64", (char *)val64);            /* secret_hash */
      sprintf((char *)tmp, "%d", ttl);
      xml_new_param(node, "int", (char *)tmp);                  /* lifetime */
      break;
    case XMLRPC_MODE_GET:
      xml_new_param(node, "int", "10");                 /* maxvals */
      xml_new_param(node, "base64", "");                /* placemark */
      memset(value, 0, *value_len);
      break;
    case XMLRPC_MODE_RM:
      memset(tmp, 0, sizeof(tmp));
      memcpy(tmp, value_hash, SHA_DIGEST_LENGTH);
      EVP_EncodeBlock(val64, tmp, SHA_DIGEST_LENGTH);
      xml_new_param(node, "base64", (char *)val64);             /* value_hash */
      xml_new_param(node, "string", "SHA");                     /* hash type */
      memset(tmp, 0, sizeof(tmp));
      memcpy(tmp, secret, secret_len);
      EVP_EncodeBlock(val64, tmp, secret_len);
      xml_new_param(node, "base64", (char *)val64);             /* secret */
      sprintf((char *)tmp, "%d", ttl);
      xml_new_param(node, "int", (char *)tmp);                  /* lifetime */
    }
  xml_new_param(node, "string", app);                   /* app */
  xmlDocDumpFormatMemory(doc, &xmlbuff, &len, 0);

  /*
   * Build an HTTP POST and transmit to server
   */
  memset(buff, 0, sizeof(buff));
  build_http_post_header(buff, len, server);       /* len is XML length above */
  memcpy(&buff[strlen(buff)], xmlbuff, len);
  xmlFree(xmlbuff);
  len = strlen(buff) + 1;
connect_retry:
  /* Connect and send the XML RPC */
  if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
      log_(WARN, "DHT connect - socket error: %s\n", strerror(errno));
      retval = -1;
      goto putget_exit;
    }
  /* Use the preferred address as source */
  memset(&src_addr, 0, sizeof(src_addr));
  src_addr.sin_family = AF_INET;
  src_addr.sin_addr.s_addr = get_preferred_addr();
  if (!src_addr.sin_addr.s_addr)
    {
      log_(NORM, "No preferred address, deferring DHT!\n");
      return(-1);
    }
  log_(NORM, "Using source address of %s for DHT %s.\n",
       logaddr(SA(&src_addr)), oper);
  fflush(stdout);
  if (bind(s, SA(&src_addr), SALEN(&src_addr)) < 0)
    {
      log_(WARN, "DHT connect - bind error: %s\n", strerror(errno));
    }

  if (g_state != 0)
    {
      return(-1);
    }
  if (retry && (retry_attempts > 0))
    {
      /* quit after a certain number of retries */
      if (retry_attempts >= HCNF.max_retries)
        {
          retval = -2;
          goto putget_exit;
        }
      /* wait packet_timeout seconds before retrying */
      hip_sleep(HCNF.packet_timeout);
    }
  retry_attempts++;

  if (connect(s, server, SALEN(server)) < 0)
    {
      log_(WARN, "DHT server connect error: %s\n", strerror(errno));
      closesocket(s);
#ifdef __WIN32__
      errno = WSAGetLastError();
      if (retry && ((errno == WSAETIMEDOUT) ||
                    (errno == WSAENETUNREACH)))
        {
          goto connect_retry;
        }
#else
      if (retry &&
          ((errno == ETIMEDOUT) || (errno == EHOSTUNREACH)))
        {
          goto connect_retry;
        }
#endif
      retval = -3;
      goto putget_exit;
    }

  if (send(s, buff, len, 0) != len)
    {
      log_(WARN, "DHT sent incorrect number of bytes\n");
      retval = -4;
      goto putget_exit;
    }
  xmlFreeDoc(doc);
  doc = NULL;

  /*
   * Receive XML RPC response from server
   */
  FD_ZERO(&read_fdset);
  FD_SET((unsigned int)s, &read_fdset);
  /* use longer timeout when retry==TRUE, because we have own thread */
  if (retry)
    {
      timeout.tv_sec = 3;
      timeout.tv_usec = 0;
    }
  else
    {
      timeout.tv_sec = 0;
      timeout.tv_usec = 300000;           /* 300ms */
    }
  if (select(s + 1, &read_fdset, NULL, NULL, &timeout) < 0)
    {
      log_(WARN, "DHT select error: %s\n", strerror(errno));
      retval = -5;
      goto putget_exit;
    }
  else if (FD_ISSET(s, &read_fdset))
    {
      if ((len = recv(s, buff, sizeof(buff) - 1, 0)) <= 0)
        {
          log_(WARN, "DHT error receiving from server: %s\n",
               strerror(errno));
          retval = -6;
          goto putget_exit;
        }
      if (strncmp(buff, "HTTP", 4) != 0)
        {
          return(-7);
        }
      if ((p = strstr(buff, "Content-Length: ")) == NULL)
        {
          return(-8);
        }
      else               /* advance ptr to Content-Length */
        {
          p += 16;
        }
      sscanf(p, "%d", &len);
      p = strchr(p, '\n') + 3;           /* advance to end of line */
      retval = hip_xmlrpc_parse_response(mode, p, len,
                                         value, value_len);
      log_(NORM, "DHT server responded with return code %d (%s).\n",
           retval, hip_xmlrpc_resp_to_str(retval));
    }
  else
    {
      /* select timeout */
      if (retry)             /* XXX testme: retry select instead? */
        {
          goto connect_retry;
        }
      retval = -9;
    }

putget_exit:
#ifdef __WIN32__
  closesocket(s);
#else
  close(s);
#endif
  if (doc != NULL)
    {
      xmlFreeDoc(doc);
    }
  if (rm_ttl > 0)
    {
      value_hash_len = sizeof(rm.value_hash);
      hip_xmlrpc_getput(((mode & 0x00F0) | XMLRPC_MODE_RM),
                        app, server, key, key_len,
                        (char *)rm.value_hash, &value_hash_len,
                        (char *)rm.secret, secret_len, rm_ttl);
    }
  return(retval);
}
Esempio n. 28
0
static void pl330_getposition(u32 dma_chan, dma_addr_t *src, dma_addr_t *dst)
{
	*src = readl(pl330_data.base + SA(dma_chan));
	*dst = readl(pl330_data.base + DA(dma_chan));
}
Esempio n. 29
0
QWidget *Expert::createTopicWidget(QDomElement &elem)
{
  QScrollArea *area   = new QScrollArea;
  QWidget     *topic  = new QWidget;
  QGridLayout *layout = new QGridLayout(topic);
  QDomElement child   = elem.firstChildElement();
  int row=0;
  while (!child.isNull())
  {
    QString type = child.attribute(SA("type"));
    if (type==SA("bool"))
    {
      InputBool *boolOption = 
          new InputBool(
            layout,row,
            child.attribute(SA("id")),
            child.attribute(SA("defval"))==SA("1"),
            child.attribute(SA("docs"))
           );
      m_options.insert(
          child.attribute(SA("id")),
          boolOption
         );
      connect(boolOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
      connect(boolOption,SIGNAL(changed()),SIGNAL(changed()));
    }
    else if (type==SA("string"))
    {
      InputString::StringMode mode;
      QString format = child.attribute(SA("format"));
      if (format==SA("dir"))
      {
        mode = InputString::StringDir;
      }
      else if (format==SA("file"))
      {
        mode = InputString::StringFile;
      }
      else // format=="string"
      {
        mode = InputString::StringFree;
      }
      InputString *stringOption = 
          new InputString(
            layout,row,
            child.attribute(SA("id")),
            child.attribute(SA("defval")),
            mode,
            child.attribute(SA("docs")),
            child.attribute(SA("abspath"))
           );
      m_options.insert(
          child.attribute(SA("id")),
          stringOption
         );
      connect(stringOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
      connect(stringOption,SIGNAL(changed()),SIGNAL(changed()));
    }
    else if (type==SA("enum"))
    {
      InputString *enumList = new InputString(
            layout,row,
            child.attribute(SA("id")),
            child.attribute(SA("defval")),
            InputString::StringFixed,
            child.attribute(SA("docs"))
           );
      QDomElement enumVal = child.firstChildElement();
      while (!enumVal.isNull())
      {
        enumList->addValue(enumVal.attribute(SA("name")));
        enumVal = enumVal.nextSiblingElement();
      }
      enumList->setDefault();

      m_options.insert(child.attribute(SA("id")),enumList);
      connect(enumList,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
      connect(enumList,SIGNAL(changed()),SIGNAL(changed()));
    }
    else if (type==SA("int"))
    {
      InputInt *intOption = 
          new InputInt(
            layout,row,
            child.attribute(SA("id")),
            child.attribute(SA("defval")).toInt(),
            child.attribute(SA("minval")).toInt(),
            child.attribute(SA("maxval")).toInt(),
            child.attribute(SA("docs"))
          );
      m_options.insert(
          child.attribute(SA("id")),
          intOption
        );
      connect(intOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
      connect(intOption,SIGNAL(changed()),SIGNAL(changed()));
    }
    else if (type==SA("list"))
    {
      InputStrList::ListMode mode;
      QString format = child.attribute(SA("format"));
      if (format==SA("dir"))
      {
        mode = InputStrList::ListDir;
      }
      else if (format==SA("file"))
      {
        mode = InputStrList::ListFile;
      }
      else if (format==SA("filedir"))
      {
        mode = InputStrList::ListFileDir;
      }
      else // format=="string"
      {
        mode = InputStrList::ListString;
      }
      QStringList sl;
      QDomElement listVal = child.firstChildElement();
      while (!listVal.isNull())
      {
        sl.append(listVal.attribute(SA("name")));
        listVal = listVal.nextSiblingElement();
      }
      InputStrList *listOption = 
          new InputStrList(
            layout,row,
            child.attribute(SA("id")),
            sl,
            mode,
            child.attribute(SA("docs"))
          );
      m_options.insert(
          child.attribute(SA("id")),
          listOption
        );
      connect(listOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
      connect(listOption,SIGNAL(changed()),SIGNAL(changed()));
    }
    else if (type==SA("obsolete"))
    {
      // ignore
    }
    else // should not happen
    {
      printf("Unsupported type %s\n",qPrintable(child.attribute(SA("type"))));
    }
    child = child.nextSiblingElement();
  }

  // compute dependencies between options
  child = elem.firstChildElement();
  while (!child.isNull())
  {
    QString dependsOn = child.attribute(SA("depends"));
    QString id        = child.attribute(SA("id"));
    if (!dependsOn.isEmpty())
    {
       Input *parentOption = m_options[dependsOn];
       Input *thisOption   = m_options[id];
       Q_ASSERT(parentOption);
       Q_ASSERT(thisOption);
       if (parentOption && thisOption)
       {
         //printf("Adding dependency '%s' (%p)->'%s' (%p)\n",
         //  qPrintable(dependsOn),parentOption,
         //  qPrintable(id),thisOption);
         parentOption->addDependency(thisOption);
       }
    }
    child = child.nextSiblingElement();
  }

  // set initial dependencies
  QHashIterator<QString,Input*> i(m_options);
  while (i.hasNext()) 
  {
    i.next();
    if (i.value())
    {
      i.value()->updateDependencies();
    }
  }

  layout->setRowStretch(row,1);
  layout->setColumnStretch(1,2);
  layout->setSpacing(5);
  topic->setLayout(layout);
  area->setWidget(topic);
  area->setWidgetResizable(true);
  return area;
}
Esempio n. 30
0
    I(total_monsters),
    I(killed_monsters),

    I(body_que),

    I(power_cubes),

    {0}
#undef _OFS
};

static const save_field_t clientfields[] = {
#define _OFS CLOFS
    I(ps.pmove.pm_type),

    SA(ps.pmove.origin, 3),
    SA(ps.pmove.velocity, 3),
    B(ps.pmove.pm_flags),
    B(ps.pmove.pm_time),
    S(ps.pmove.gravity),
    SA(ps.pmove.delta_angles, 3),

    V(ps.viewangles),
    V(ps.viewoffset),
    V(ps.kick_angles),

    V(ps.gunangles),
    V(ps.gunoffset),
    I(ps.gunindex),
    I(ps.gunframe),