/** * @param string $ip * @param int $port * @return bool */ public function connect($ip, $port = 1080) { $this->ip = $ip; $this->port = $port; $sock_path = $this->sock_path(); if ($this->client->connect($sock_path)) { JAXLLogger::debug("established connection to {$sock_path}"); return true; } else { JAXLLogger::error("unable to connect {$sock_path}"); return false; } }
public function on_server_accept_ready($server) { //JAXLLogger::debug("got server accept"); $client = @stream_socket_accept($server, 0, $addr); if (!$client) { JAXLLogger::error("unable to accept new client conn"); return; } if (@stream_set_blocking($client, $this->blocking)) { $client_id = (int) $client; $this->clients[$client_id] = array('fd' => $client, 'ibuffer' => '', 'obuffer' => '', 'addr' => trim($addr), 'close' => false, 'closed' => false, 'reading' => false, 'writing' => false); JAXLLogger::debug("accepted connection from client#" . $client_id . ", addr:" . $addr); // if accept callback is registered // callback and let user land take further control of what to do if ($this->accept_cb) { call_user_func($this->accept_cb, $client_id, $this->clients[$client_id]['addr']); } else { // if no accept callback is registered // close the accepted connection if (is_resource($client)) { fclose($client); } $this->clients[$client_id]['closed'] = true; unset($this->clients[$client_id]); } } else { JAXLLogger::error("unable to set non block flag"); } }
public function handle_invalid_state($r) { JAXLLogger::error("got invalid event {$r}"); }
public function recv() { if ($this->restarted) { $this->restarted = false; // fool xmpp_stream state machine with stream start packet // and make transition to wait_for_stream_features state if ($this->recv_cb) { call_user_func($this->recv_cb, $this->jaxl->get_start_stream(new XMPPJid("bosh.jaxl"))); } } JAXLLogger::debug("recving for {$this->rid}"); do { $mrc = curl_multi_exec($this->mch, $running); JAXLLogger::debug("mrc={$mrc} running={$running}"); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($running && $mrc == CURLM_OK) { $ms = curl_multi_select($this->mch, 0.1); if ($ms != -1) { do { $mrc = curl_multi_exec($this->mch, $running); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } $ch = isset($this->chs[$this->rid]) ? $this->chs[$this->rid] : false; if ($ch) { $data = curl_multi_getcontent($ch); curl_multi_remove_handle($this->mch, $ch); unset($this->chs[$this->rid]); JAXLLogger::debug("recvd for {$this->rid} " . $data); list($body, $stanza) = $this->unwrap($data); $body = new SimpleXMLElement($body); $attrs = $body->attributes(); if (isset($attrs['type']) && $attrs['type'] == 'terminate') { // fool me again if ($this->recv_cb) { call_user_func($this->recv_cb, $this->jaxl->get_end_stream()); } } else { if (!$this->sid) { $this->sid = $attrs['sid']; } if ($this->recv_cb) { call_user_func($this->recv_cb, $stanza); } } } else { JAXLLogger::error("no ch found"); exit; } }
public function handle_auth_mechs($stanza, $mechanisms) { if ($this->ev->exists('on_stream_features')) { return $this->ev->emit('on_stream_features', array($stanza)); } // extract available mechanisms $mechs = array(); if ($mechanisms) { foreach ($mechanisms->children as $mechanism) { $mechs[$mechanism->text] = true; } } $pref_auth = $this->cfg['auth_type']; // check if preferred auth type exists in available mechanisms if (isset($mechs[$pref_auth]) && $mechs[$pref_auth]) { JAXLLogger::debug("pref_auth " . $pref_auth . " exists"); } else { JAXLLogger::debug("pref_auth " . $pref_auth . " doesn't exists"); JAXLLogger::error("preferred auth type not supported, trying {$pref_auth}"); } $this->send_auth_pkt($pref_auth, isset($this->jid) ? $this->jid->to_string() : null, $this->pass); if ($pref_auth == 'CRAM-MD5') { return "wait_for_cram_md5_response"; } elseif ($pref_auth == 'SCRAM-SHA-1') { return "wait_for_scram_sha1_response"; } }
/** * @param string | resource $socket_path */ public function connect($socket_path) { if (gettype($socket_path) == "string") { $path_parts = explode(":", $socket_path); $this->transport = $path_parts[0]; $this->host = substr($path_parts[1], 2, strlen($path_parts[1])); if (count($path_parts) == 3) { $this->port = $path_parts[2]; } JAXLLogger::info("trying " . $socket_path); if ($this->stream_context) { $this->fd = @stream_socket_client($socket_path, $this->errno, $this->errstr, $this->timeout, STREAM_CLIENT_CONNECT, $this->stream_context); } else { $this->fd = @stream_socket_client($socket_path, $this->errno, $this->errstr, $this->timeout); } } elseif (is_resource($socket_path)) { $this->fd =& $socket_path; } else { // Some error occurred. } if ($this->fd) { JAXLLogger::debug("connected to " . $socket_path . ""); stream_set_blocking($this->fd, $this->blocking); // watch descriptor for read/write events JAXLLoop::watch($this->fd, array('read' => array(&$this, 'on_read_ready'))); return true; } else { JAXLLogger::error(sprintf("unable to connect %s with error no: %s, error str: %s", is_null($socket_path) ? 'NULL' : $socket_path, is_null($this->errno) ? 'NULL' : $this->errno, is_null($this->errstr) ? 'NULL' : $this->errstr)); $this->disconnect(); return false; } }
public function handle_invalid_state($r) { JAXLLogger::error(sprintf("got invalid return value from state handler '%s', sending end stream...", $this->state)); $this->send_end_stream(); $this->state = "logged_out"; JAXLLogger::notice(sprintf("state handler '%s' returned %s, kindly report this to developers", $this->state, serialize($r))); }
protected function handle_start_tag($parser, $name, array $attrs) { $name = $this->explode($name); //echo "start of tag ".$name[1]." with ns ".$name[0].PHP_EOL; // replace ns with prefix foreach ($attrs as $key => $v) { $k = $this->explode($key); // no ns specified if ($k[0] == null) { $attrs[$k[1]] = $v; } elseif ($k[0] == XMPP::NS_XML) { // xml ns unset($attrs[$key]); $attrs['xml:' . $k[1]] = $v; } else { JAXLLogger::error("==================> unhandled ns prefix on attribute"); // remove attribute else will cause error with bad stanza format // report to developer if above error message is ever encountered unset($attrs[$key]); } } if ($this->depth <= 0) { $this->depth = 0; $this->ns = $name[1]; if ($this->start_cb) { $stanza = new JAXLXml($name[1], $name[0], $attrs); call_user_func($this->start_cb, $stanza); } } else { if (!$this->stanza) { $stanza = new JAXLXml($name[1], $name[0], $attrs); $this->stanza =& $stanza; } else { $this->stanza->c($name[1], $name[0], $attrs); } } ++$this->depth; }
public static function select() { $read = self::$read_fds; $write = self::$write_fds; $except = null; $changed = @stream_select($read, $write, $except, self::$secs, self::$usecs); if ($changed === false) { JAXLLogger::error("error in the event loop, shutting down..."); /*foreach (self::$read_fds as $fd) { if (is_resource($fd)) { print_r(stream_get_meta_data($fd)); } }*/ exit; } elseif ($changed > 0) { // read callback foreach ($read as $r) { $fdid = array_search($r, self::$read_fds); if (isset(self::$read_fds[$fdid])) { call_user_func(self::$read_cbs[$fdid], self::$read_fds[$fdid]); } } // write callback foreach ($write as $w) { $fdid = array_search($w, self::$write_fds); if (isset(self::$write_fds[$fdid])) { call_user_func(self::$write_cbs[$fdid], self::$write_fds[$fdid]); } } self::$clock->tick(); } elseif ($changed === 0) { //JAXLLogger::debug("nothing changed while selecting for read"); self::$clock->tick(self::$secs * pow(10, 6) + self::$usecs); } }
/** * @param string $name * @param callable $read_cb TODO: Currently not used */ public function __construct($name, $read_cb = null) { // TODO: see JAXL->cfg['priv_dir'] $this->pipes_folder = getcwd() . '/.jaxl/pipes'; if (!is_dir($this->pipes_folder)) { mkdir($this->pipes_folder, 0777, true); } $this->ev = new JAXLEvent(); $this->name = $name; // TODO: If someone's need the read callback and extends the JAXLPipe // to obtain it, one can't because this property is private. $this->read_cb = $read_cb; $pipe_path = $this->get_pipe_file_path(); if (!file_exists($pipe_path)) { posix_mkfifo($pipe_path, $this->perm); $this->fd = fopen($pipe_path, 'r+'); if (!$this->fd) { JAXLLogger::error("unable to open pipe"); } else { JAXLLogger::debug("pipe opened using path {$pipe_path}"); JAXLLogger::notice("Usage: \$ echo 'Hello World!' > {$pipe_path}"); $this->client = new JAXLSocketClient(); $this->client->connect($this->fd); $this->client->set_callback(array(&$this, 'on_data')); } } else { JAXLLogger::error("pipe with name {$name} already exists"); } }