X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/includes/libs/UDPTransport.php diff --git a/includes/libs/UDPTransport.php b/includes/libs/UDPTransport.php new file mode 100644 index 00000000..7fad882a --- /dev/null +++ b/includes/libs/UDPTransport.php @@ -0,0 +1,102 @@ +host = $host; + $this->port = $port; + $this->domain = $domain; + $this->prefix = $prefix; + } + + /** + * @param string $info In the format of "udp://host:port/prefix" + * @return UDPTransport + * @throws InvalidArgumentException + */ + public static function newFromString( $info ) { + if ( preg_match( '!^udp:(?://)?\[([0-9a-fA-F:]+)\]:(\d+)(?:/(.*))?$!', $info, $m ) ) { + // IPv6 bracketed host + $host = $m[1]; + $port = intval( $m[2] ); + $prefix = isset( $m[3] ) ? $m[3] : false; + $domain = AF_INET6; + } elseif ( preg_match( '!^udp:(?://)?([a-zA-Z0-9.-]+):(\d+)(?:/(.*))?$!', $info, $m ) ) { + $host = $m[1]; + if ( !IP::isIPv4( $host ) ) { + $host = gethostbyname( $host ); + } + $port = intval( $m[2] ); + $prefix = isset( $m[3] ) ? $m[3] : false; + $domain = AF_INET; + } else { + throw new InvalidArgumentException( __METHOD__ . ': Invalid UDP specification' ); + } + + return new self( $host, $port, $domain, $prefix ); + } + + /** + * @param string $text + */ + public function emit( $text ) { + // Clean it up for the multiplexer + if ( $this->prefix !== false ) { + $text = preg_replace( '/^/m', $this->prefix . ' ', $text ); + + // Limit to 64KB + if ( strlen( $text ) > 65506 ) { + $text = substr( $text, 0, 65506 ); + } + + if ( substr( $text, -1 ) != "\n" ) { + $text .= "\n"; + } + } elseif ( strlen( $text ) > 65507 ) { + $text = substr( $text, 0, 65507 ); + } + + $sock = socket_create( $this->domain, SOCK_DGRAM, SOL_UDP ); + if ( !$sock ) { // @todo should this throw an exception? + return; + } + + socket_sendto( $sock, $text, strlen( $text ), 0, $this->host, $this->port ); + socket_close( $sock ); + } +}