フェルミ推定を用いた、サマータイム対応にかかるコスト試算

■はじめに
ここでは、フェルミ推定を用いサマータイムの対応にかかるコストを粗々に試算をすることで、最低どれだけの富が無為に失われるかについて明らかにする。


■前提
フェルミ推定については下記を参照のこと
https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A7%E3%83%AB%E3%83%9F%E6%8E%A8%E5%AE%9A


推定に用いる数値についてはできるだけ、政府統計など公的な、あるいはそれに近いものを用い、出典についても可能な限り記述する。
また、あて推量が必要なものについても可能な限り実例を用い、非現実的な数値にならないよう心掛ける


■推定
まず、サマータイム対応にかかる大きなコストとしては、次の3つが考えられる。
1. 各家庭での時計合わせを行う作業にかかわるコスト
2. いわゆるコンピュータシステムの改修作業にかかわるコスト


〇1. 各家庭での時計合わせを行う作業にかかわるコスト
これは粗々に考えると、ご家庭の数 × 設定を要する機器の数 × 設定にかかる時間 × 時間当たりの人件費 で推定できると思われる。
それぞれについて下記のように推定する


1-1. ご家庭の数
これは そのまま日本における世帯数であり、下記を参照できる


https://www.e-stat.go.jp/dbview?sid=0003169257
表より 世帯数の総数 5036.1万世帯


1-2. 設定を要する機器の数
これは、当て推量が必要となる。
一人暮らしの家庭に存在する、時計を持つ機器を一つずつ挙げてくことで推定する。
PC、プリンタ、携帯電話、TV、据え置き型ゲーム機器、携帯型ゲーム機器、壁掛け時計、置時計、カメラ、インターフォン、冷蔵庫、湯沸し器、電子レンジ、炊飯器、電気ポット、ロボット掃除機、エアコン、洗濯機
さしあたり、18個程挙がった
実際には、複数人の世帯では、TVやPC、携帯電話などは複数所持すると考えられるがここではそこら辺の誤差は無視する


1-3. 設定にかかる時間
これは、当て推量が必要となる。
ここでは、設定が面倒な機器や、簡単な機器があることを考慮して、1つあたり2分= 60分の2時間 と仮定する


1-4. 時間当たりの人件費
これは、平均年収 ÷ 12 か月 ÷ 21 営業日 ÷ 勤務時間(8時間) で推定できる。


平均年収は下記を参照できる
https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&tstat=000001012969&cycle=7&year=20160&month=0&result_back=1&second2=1&tclass1val=0
PDFのP12 第8表によれば 平成28年度の 平均給与 420.4万円


計算すると 420.4万円 ÷ 12か月 ÷ 21日 ÷ 8時間 = 0.20853174603 ≒ 時間あたり2085円


1-A. 計算
上記で求めた値よりコストを計算する


世帯数の総数 5036.1万世帯 × 設定を要する機器の数 18個 × × 設定にかかる時間 60分の2時間 × 時間当たりの人件費2085円 = 6300161.1万円 ≒ 630億円


〇2. いわゆるコンピュータシステムの改修作業にかかわるコスト
これは粗々に考えると、同じ日時関連の改修を行ったいわゆる2000年問題での対応費用と同程度として推定する で推定できると思われる。


https://www.kantei.go.jp/jp/pc2000/houkokusyo/honbun.html
上記記によれば
97年10月の(社)情報サービス産業協会の調査に基づく試算では、約1.3〜2.4兆円となっている。また、金融監督庁によれば、金融機関等の費用の見積もりは、99年6月末時点で、約7000億円とされている。


金融機関のみで7000億円かかるというのだから、コンピュータシステム全体では前者の資産の上限2.4兆円を採用するのが妥当であろうと思われる。


■その他検討事項
その他の問題として、サマータイムへの対応を行うことで、エンジニアの払底が起こり、本来であれば行えたはずのそのほかの「価値を生むための」システムの開発などが行えなくなる影響も推測される。
これによって得られたはずの価値喪失分もカウントする必要があるだろう。


■結論
各家庭での時計合わせを行う作業にかかわるコスト として 630億円程度
いわゆるコンピュータシステムの改修作業にかかわるコスト として 2.4兆円程度
その他の本来得られたはずの価値喪失分 不明


最終的には 総計 2.5兆円 以上のコストが「何も価値を生まない」コストとして支払われることになると推測される。

フレームワークをつくってみる


このブログもだいぶ更新をさぼってしまった。
ひとつ前の記事が2016年09月24日だから、ざっくり23か月程更新されていない計算になる。


さすがに、もうこのブログを読んでいる人もいるまい。
…ということで、ブログの内容を大きく変えてみることにした。

  • どんな内容にするか?

最近、寝る前の1時間ほどを使って、個人的なプロジェクトを立ち上げたのでそれについてだらだらと書いていきたいと思う。

  • 個人的なプロジェクトとは何か?

PHPフレームワークを新たに開発しようと思う。

私事だが、ここ最近、会社の事情でいわゆるインフラ運用系の部署に所属することになった。
そこでは、いわゆるプログラミングの仕事は決して多いとは言えず、このままではプログラミングのスキルがさび付いてしまうのではないかという危機感がある。
まずは、これが一つ
もう一点は、部署移動の前まで社内の独自フレームワークの主設計者かつ、リードプログラマーとして開発していたのだが、移動に伴いその開発に一切かかわれなくなってしまい、フレームワークを十分熟成したものに育てられなかった悔しさのようなものがある。

1. まず、なにより誰でもわかりやすく、入社したての新人でも簡単に書けるものを目指す
2. コードジェネレーターなどの支援機能をもちいてコードやHTMLテンプレートの自動生成が行えるもの
3. テンプレート、WebAPI、Restと複数のI/Fを持ち、フロントエンドエンジニア もしくは Webデザイナーと協調開発ができるもの
4. MVCモデルを基本としつつ、必要な個所については別途レイヤーを持つもの
5. スマホ世代のWebサイトやアプリに必要な機能を備えたもの
6. いくつかのPSRに準拠することを目指す

未定
開発を進め、フレームワークの方向性が固まった段階で名前を付けたい。
もしくは、使ってみたい or 使ってみた人が多いようなら公募を募ってもいいかもしれない

  • コードネームは無いのか?

コードネームは移動前に作っていたフレームワークのものを継承して次のように定めた。
もっとも初期に開発された携帯向けフレームワーク mr、それを一歩進めた、スマートフォン世代への対応と、コードの近代化を図った ns(New System、Next Site)。
そして、それに続く次のフレームワークとして ot と名付ける。
(お気づきの方もいるかと思うが、コードネームは前の世代のフレームワークのアルファベットを一文字づつずらしたものである)


ot には 次の3つの意味を込ようと思う
1つは、目標 としての Over Technology、つまり現在の技術を超えた先オーバーテクノロジーに至ること
1つは、思想 としての Open Technology、つまりいかなる時も開かれたオープンな技術であること
1つは、未来 としての Ordinary Technology、つまり普通の技術として広く定着することを祈って

初期の環境構築等が終わったらGitHubなりどこかにスペースを作る予定



不明
頑張ってみるけど、失踪したら申し訳ない

PHP7.0世代のハッシュ、暗号化、暗号論的乱数生成およびCSRF対策周りのメモ

独自フレームワークのPHP7対応に絡んで、認証 および CSRF対策周りを再設計したいので予備調査の結果を軽くまとめる


ハッシュ関係

  • password_hash関数 パスワード認証用のハッシュ生成に使う
  • password_verify関数 タイミング攻撃を回避するための文字列比較関数(password_hash専用)
  • hash関数 通常のハッシュ生成に使う(MD5とか、SHA256とか)
  • hash_equals関数 タイミング攻撃を回避するための文字列比較関数(汎用)、== や === はタイミング攻撃が可能
  • パスワード認証と、それ以外で用途により使い分ける形がベストか?


暗号関係


暗号論的乱数生成関係


CSRF対策

  • ワンタイムトークン利用 に加え、POSTに限定する、リファラ―の変更がないことを確認する
  • また、トークン発行画面はキャッシュされないようヘッダーを吐く
    • Apacheのmod_expires、mod_headers に任せるのも一考
    • ヘッダーの例

header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' );
header( 'Last-Modified: '.gmdate( 'D, d M Y H:i:s' ).' GMT' );

// HTTP/1.1の場合
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Cache-Control: post-check=0, pre-check=0', FALSE );

// HTTP/1.0の場合
header( 'Pragma: no-cache' );

phpDocumentor version 2.8.5 の PHP7対応

phpDocumentor version 2.8.5 の PHP7対応時に嵌った&修正した項目を荒くメモしておく
とりあえず、動くようにしただけなので、全ての環境で動くわけではない

インストールは下記で実施


pear channel-discover pear.phpdoc.org
pear install phpdoc/phpDocumentor

実行時に結果を置くディレクトリを空にしておかないと Segmentation fault が発生する


rm -rf /home/hoge/phpdoc/htdocs/*



PHP7では opcache.load_comments の設定が無効なので、下記のエラーが起こる
ini_get('opcache.load_comments') の結果が 0 なのか NULL なのか厳密に判別してないため、エラーになる模様


[root@dev htdocs]# phpdoc -d /home/hoge/libphp/API/ -t /home/hoge/phpdoc/htdocs/
PHP Fatal error: Uncaught Doctrine\Common\Annotations\AnnotationException: You have to enable opcache.load_comments=1 or zend_optimizerplus.load_comments=1. in /usr/local/lib64/php/phpDocumentor/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php:193
Stack trace:
#0 /usr/local/lib64/php/phpDocumentor/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php(171): Doctrine\Common\Annotations\AnnotationException::optimizerPlusLoadComments()
#1 /usr/local/lib64/php/phpDocumentor/vendor/jms/serializer/src/JMS/Serializer/SerializerBuilder.php(338): Doctrine\Common\Annotations\AnnotationReader->__construct()
#2 /usr/local/lib64/php/phpDocumentor/src/Cilex/Provider/JmsSerializerServiceProvider.php(73): JMS\Serializer\SerializerBuilder->build()
#3 /usr/local/lib64/php/phpDocumentor/vendor/pimple/pimple/lib/Pimple.php(126): Cilex\Provider\JmsSerializerServiceProvider->Cilex\Provider\{closure}(Object(phpDocumentor\Application))
#4 /usr/local/lib64/php/phpDocumentor/vendor/pimple/pi in /usr/local/lib64/php/phpDocumentor/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php on line 193

Fatal error: Uncaught Doctrine\Common\Annotations\AnnotationException: You have to enable opcache.load_comments=1 or zend_optimizerplus.load_comments=1. in /usr/local/lib64/php/phpDocumentor/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php on line 193

Doctrine\Common\Annotations\AnnotationException: You have to enable opcache.load_comments=1 or zend_optimizerplus.load_comments=1. in /usr/local/lib64/php/phpDocumentor/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php on line 193

Call Stack:
0.0002 355064 1. {main}() /usr/local/bin/phpdoc:0
0.0004 371048 2. phpDocumentor\Bootstrap->initialize() /usr/local/bin/phpdoc:23
0.0060 1642536 3. phpDocumentor\Application->__construct() /usr/local/lib64/php/phpDocumentor/src/phpDocumentor/Bootstrap.php:62
0.0067 1682552 4. phpDocumentor\Application->addLogging() /usr/local/lib64/php/phpDocumentor/src/phpDocumentor/Application.php:67
0.0073 1759328 5. Pimple->offsetGet() /usr/local/lib64/php/phpDocumentor/src/phpDocumentor/Application.php:254
0.0073 1759328 6. Pimple::{closure:/usr/local/lib64/php/phpDocumentor/vendor/pimple/pimple/lib/Pimple.php:122-130}() /usr/local/lib64/php/phpDocumentor/vendor/pimple/pimple/lib/Pimple.php:83
0.0073 1759352 7. phpDocumentor\Configuration\ServiceProvider->phpDocumentor\Configuration\{closure}() /usr/local/lib64/php/phpDocumentor/vendor/pimple/pimple/lib/Pimple.php:126
0.0074 1772520 8. Pimple->offsetGet() /usr/local/lib64/php/phpDocumentor/src/phpDocumentor/Configuration/ServiceProvider.php:80
0.0074 1772520 9. Pimple::{closure:/usr/local/lib64/php/phpDocumentor/vendor/pimple/pimple/lib/Pimple.php:122-130}() /usr/local/lib64/php/phpDocumentor/vendor/pimple/pimple/lib/Pimple.php:83
0.0074 1772544 10. Cilex\Provider\JmsSerializerServiceProvider->Cilex\Provider\{closure}() /usr/local/lib64/php/phpDocumentor/vendor/pimple/pimple/lib/Pimple.php:126
0.0090 2000296 11. JMS\Serializer\SerializerBuilder->build() /usr/local/lib64/php/phpDocumentor/src/Cilex/Provider/JmsSerializerServiceProvider.php:73
0.0093 2060856 12. Doctrine\Common\Annotations\AnnotationReader->__construct() /usr/local/lib64/php/phpDocumentor/vendor/jms/serializer/src/JMS/Serializer/SerializerBuilder.php:338


vi /usr/local/lib64/php/phpDocumentor/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php
L193 近辺


if (extension_loaded('Zend OPcache') && ini_get('opcache.load_comments') == 0) {
throw AnnotationException::optimizerPlusLoadComments();
}

↓↓↓↓↓↓

if (extension_loaded('Zend OPcache') && ini_get('opcache.load_comments') === 0) {
throw AnnotationException::optimizerPlusLoadComments();
}




タイプヒンティング時の厳密な型判定により引っ掛かった?

vi /usr/local/lib64/php/phpDocumentor/vendor/monolog/monolog/src/Monolog/ErrorHandler.php


public function handleException(\Exception $e)

↓↓↓↓↓↓

public function handleException(Exception $e)





http://php.net/manual/ja/migration70.incompatible.php
↑の変数の取り扱いの変更の影響(Changes to the handling of indirect variables, properties, and methods)で、扱いが変わった


下記のようなNoticeが発生し、ドキュメント上に出力される


Notice: Array to string conversion in /usr/local/lib64/php/phpDocumentor/vendor/erusev/parsedown/Parsedown.php on line 1404
... 略 ...
Notice: Undefined property: Parsedown::$Array in /usr/local/lib64/php/phpDocumentor/vendor/erusev/parsedown/Parsedown.php on line 1404
... 略 ...

vi /usr/local/lib64/php/phpDocumentor/vendor/erusev/parsedown/Parsedown.php


if (isset($Element['handler']))
{
$markup .= $this->$Element['handler']($Element['text']);
}

↓↓↓↓↓↓

if (isset($Element['handler']))
{
$handler = $Element['handler'];
$markup .= $this->$handler($Element['text']);
}

PHP 5.3.10 における参照時の謎挙動

久々におかしな仕様?バグ?にであったのでメモしておく。

問1: 下記のコードについて実行結果を予測し解答せよ

?php
function drct($input) {}
$hoge = array();
drct($hoge['aaa']);
echo var_export($hoge, true)."\n";

問2: 下記のコードについて実行結果を予測し解答せよ

<?php
function ref(&$input) {}
$hoge = array();
ref($hoge['aaa']);
echo var_export($hoge, true)."\n";

手元のPHP 5.3.10にて確認したところ下記のような結果が得られた
答1:

[hoge@localhost ~]$ php ./test.php
PHP Notice:  Undefined index: aaa in /home/hoge/test.php on line 4
PHP Stack trace:
PHP   1. {main}() /home/hoge/test.php:0

Notice: Undefined index: aaa in /home/hoge/test.php on line 4

Call Stack:
    0.0005     632544   1. {main}() /home/hoge/test.php:0

array (
)

答2:

array (
  'aaa' => NULL,
)


答1 の結果は想定どおりの動きだが、答2の動きは予期しない動きではないだろうか?
おそらく、参照された瞬間に空の変数が生成されているっぽい

参照で渡した場合にNoticeがおきないことを利用してコードを書いている場合、気をつけないとこの副作用でバグを生む可能性があるので要注意


一応下記のように回避することも出来るが、これも$hoge['aaa'] がすでにセットされている場合に副作用があるので注意

<?php
function ref(&$input) { }
$hoge = array();
ref($hoge['aaa']);
unset($hoge['aaa']); 
echo var_export($hoge, true)."\n";

「通信の最適化」問題の論点まとめ

注意:
途中で力尽きました、ぜんぜんまとめきれてません・・・orz



○通信の最適化とは
いわゆる3大キャリアを中心に、MVNOなども含む非wifi通信時(いわゆるLTEなど)におこなわれる、画像、動画等に対する非可逆圧縮のこと


○問題点
問題点としては複数あり、主に下記のように類型化できると思われる
1. 品質劣化の問題
各サービス提供者もしくはユーザーの意図に反する形で(あるいは基づかない形で)、画像等に対する非可逆圧縮をおこない品質劣化をおこしている点
2. サービスへの干渉の問題
一部のアプリにおいて「通信の最適化」によりアプリを起動できないなどの問題が発生し、各サービス提供者およびユーザーに不利益を与えている点
3. 通信の秘密への侵害の問題
ユーザによる「明確な同意」に基づかずにおこなっており、いいわゆる電気通信事業法 および 日本国憲法 における「通信の秘密」を侵しており、盗聴や検閲に相当する点
4. ネットワーク中立性に反する問題
インターネットのユーザーが自分が見るコンテンツや使用するアプリケーションを自分で選択できるべきだとするネットワーク中立性の考え方に反する点
5. 著作権の侵害の問題
画像等の非可逆圧縮をおこなうことから著作権における同一性保持権を侵害している点
6. その他



○通信の最適化はどのように実現されるか
ドコモ、auSoftbank、その他MVNOなどで差異はあるが主として下記のようにな構造が想像される

+-------------------------+
| クライアント            | ... ユーザーからみるとブラウザやアプリ相当
+-------------------------+
   ↓              ↑
  ( LTEなどのキャリア網 )
   ↓              ↑
+-------------------------+
| 透過的Proxy              | ... ここで一部のレスポンスに対して非可逆圧縮を実施
+-------------------------+
   ↓              ↑
  ( インターネット網 )
   ↓              ↑
+-------------------------+
| サービス提供者のサーバー |
+-------------------------+

凡例
↓ --- リクエスト
↑ --- レスポンス

各キャリアとも「通信の最適化」の詳細な仕組みや非可逆圧縮の対象の選定方法などは公開されていないため想像になるが
いわゆるキャリア網とインターネット網の境界付近に透過的Proxyを配置しそこで通信パケットを一次復元し画像、動画、音声などに対して非可逆圧縮をかけていると想定される。


○同一レイヤー同一ペイロードの原則(造語)について
話をわかりやすくするため先に、余計な話をしておこう


いわゆる、「インターネット」はサーバーとクライアントがありその間にネットワークがあるという形が基本となっているかと思う。
クライアントがネットワークを介してサーバーに対しリクエストを行い、サーバはレスポンスとして結果を返すというのが基本的なフローである。
ネットワーク内ではリクエストやレスポンスは、いわゆるプロトコルスタックにしたがって分割、パケットか、信号化され最終的には電気信号や光として伝達される。
一般的に教科書的に想定されるウェブブラウズにおけるプロトコルスタックとしては、低レイヤーから順に 100BASE-TX - 802.3(ethernet) - IP - TCP - HTTP - アプリ(プログラム、ブラウザ) といったものあたりが想定されると思われる。


ここで、とあるクライアントと、とあるサーバーが通信する場合を単純化してかんがえると、クライアントは高いレイヤーから順にプロトコルスタックをたどって100BASE-TXの信号としてリクエストをネットワークに送出する
これに対してサーバーは信号として100BASE-TXの信号としてリクエストを受け取り低いレイヤーから順にプロトコルスタックをさかのぼって解釈しリクエストを受け取り、プログラムで処理し、それに対して今度は逆順にレスポンスを返し、最終的にブラウザに表示されるといった流れとなる


ここで、このリクエスト or レスポンスのクライアント側とサーバー側で同一のレイヤー(同一のプロトコル)のいわゆるペイロード部分だけを注目した場合、どちらのプロトコルスタック上でも同じレイヤーにおけるペイロード部分の総体(あくまで総体であって個別のパケットは分割されていたり順番が相違することなどはありうる)はどちらも同一であることが原則として保障される。
このペイロードの総体が同一であることが保障されていることでインターネット網での正常な通信が可能になる。
たとえば、レスポンスを対象として、サーバ側でHTTPの層でペイロードgzip圧縮(可逆圧縮)(HTTPのContent-Encodingの機能)したとしても、クライアントでgzipされたペイロードをHTTPの層で受け取り、それを解凍して上位の層に渡すので、双方のアプリの層では同じペイロードが得られる

従来のレスポンス
 サーバー                                                    クライアント
+--------------------------------+ (1)                   (1)+--------------------------------+
| アプリ(サーバ側プログラム)     | ↓<-                ->→ | アプリ(クライアント側ブラウザ) |
+--------------------------------+ ↓                    ↑ +--------------------------------+
| HTTP                           | ↓<- 各層で見ると   ->↑ | HTTP                           |
+--------------------------------+ ↓                    ↑ +--------------------------------+
| TCP                            | ↓<- 総体として同一 ->↑ | TCP                            |
+--------------------------------+ ↓                    ↑ +--------------------------------+
| IP                             | ↓<-                ->↑ | IP                             |
+--------------------------------+ ↓                    ↑ +--------------------------------+
| 802.3(ethernet)                | ↓<-                ->↑ | 802.3(ethernet)                |
+--------------------------------+ ↓                    ↑ +--------------------------------+
| 100BASE-TX                     | →→→→(中略)→→→→↑ | 100BASE-TX                     |
+--------------------------------+                          +--------------------------------+
従来のレスポンスは(1)のペイロードの総体はサーバー、クライアント間で維持される
また、中略の部分に無線LANや光ファイバー、ハブやL2スイッチ、ルータなどなどが存在している想定だが
その場合であっても、総体としてのペイロードは維持される


今回の「通信の最適化」ではこの総体としてペイロードが同一であることが、通信経路におかれた透過的Proxyによる非可逆圧縮の影響で最上位のアプリの層で崩れてしまうことで、アプリに悪影響を与えてしまっている。

「通信の最適化」のレスポンス
 サーバー                                                    透過的Proxy(ここで改変)                                 クライアント
+--------------------------------+ (2)                   (2)+--------------------------------+(2')                  (2')+--------------------------------+
| アプリ(サーバ側プログラム)     | ↓<-                ->→ | 画像、動画などの圧縮プログラム | ↓<-                ->→ | アプリ(クライアント側ブラウザ) |
+--------------------------------+ ↓                    ↑ +--------------------------------+ ↓                    ↑ +--------------------------------+
| HTTP                           | ↓<- 各層で見ると   ->↑ | HTTP                           | ↓<- 各層で見ると   ->↑ | HTTP                           |
+--------------------------------+ ↓                    ↑ +--------------------------------+ ↓                    ↑ +--------------------------------+
| TCP                            | ↓<- 総体として同一 ->↑ | TCP                            | ↓<- 総体として同一 ->↑ | TCP                            |
+--------------------------------+ ↓                    ↑ +--------------------------------+ ↓                    ↑ +--------------------------------+
| IP                             | ↓<-                ->↑ | IP                             | ↓<-                ->↑ | IP                             |
+--------------------------------+ ↓                    ↑ +--------------------------------+ ↓                    ↑ +--------------------------------+
| 802.3(ethernet)                | ↓<-                ->↑ | 802.3(ethernet)                | ↓<-                ->↑ | 802.3(ethernet)                |
+--------------------------------+ ↓                    ↑ +--------------------------------+ ↓                    ↑ +--------------------------------+
| 100BASE-TX                     | →→→→(中略)→→→→↑ | 100BASE-TX                     | →→→→(中略)→→→→↑ | 100BASE-TX                     |
+--------------------------------+                          +--------------------------------+                          +--------------------------------+
「通信の最適化」のレスポンス(2)のペイロードの総体はサーバー、クライアント間で維持されず、Proxyで改変された(2')を受け取ってしまう

また、中略の部分に無線LAN光ファイバー、ハブやL2スイッチ、ルータなどなどが存在している想定だが
その場合であっても、 サーバー - Proxy間、Proxy - クライアント間の総体としてのペイロードはそれぞれ維持される



○「通信の最適化」の対象になっているか調べる方法


・対象かどうか
まずは第一に3大キャリアの設定ページにて、自分が対象になっているのか確認する方法は、下記を参照にすると良いだろう


「通信の最適化」を設定・解除する方法【ドコモ・auソフトバンク】 ? WEBサイトでチェックもできるぞ ≫ 使い方・方法まとめサイト - usedoor
http://usedoor.jp/howto/digital/smartphone/tsuushinnosaitekika-docomo-au-softbank/


・今現在「通信の最適化」されているかどうか
いくつかのサイトで今現在「通信の最適化」がされているか確認することが出来る
有名どころを二つほど上げておくので参照してみると良いと思う


「通信の最適化」テストページ
http://seaki.sastudio.jp/nise/photos/SANY9274i.html


通信の最低^H^H最適化の確認
http://horobi.com/Saiteika/



・過去に「通信の最適化」されていた可能性があるかどうか
これまでの報告によると、ドコモ、auSoftbankBIGLOBEb-mobile、U-mobile、ぷららモバイルLTEDTIなどで「通信の最適化」が報告されています


「通信の最適化」、3キャリアと11社のMVNOで適用実態を調べてみた | 格安スマホ回線研究所
http://yesmvno.com/optimization/


なお、IIJmio については下記のTweetによれば、現時点では行っておらず、導入の予定も(いまのところ)ない とのこと
https://twitter.com/iijmio/status/615456060028006400


加えて、下記にて紹介されているが Google Chromeの「データセーバー」や、Operaの「Turboモード」など意図して「通信の最適化」をする機能を意図して利用している場合、今回のキャリアによる「通信の最適化」とは別に適用されている場合があるので注意が必要です。


MVNO格安SIM)であえて「通信の最適化」をする方法 | エンジニアの休日
http://xins.club/lab/mvno-optimization-apk/



○これまでの流れ
おおよそ下記のまとめを追うと大まかな流れは確認できると思われる


ハッハッ、見ろ!第1種電気通信事業がゴミのようだ!! #通信の最適化() - Togetterまとめ
http://togetter.com/li/839917


高木浩光先生、通信の最適化についてau電凸(前編)「元に戻せない圧縮であるが、改ざんではない」 - Togetterまとめ
http://togetter.com/li/846035


高木浩光先生、通信の最適化についてau電凸(後編)「そんな適当なこと言って大丈夫か?」「大丈夫だ、問題ない」 - Togetterまとめ
http://togetter.com/li/846061


kadongo38氏「日本の通信事業者よりAppleFacebook, Google の方が問題」 - Togetterまとめ
http://togetter.com/li/847364


通信の最適化に対するshi3zさんのネットワーク構成認識 - Togetterまとめ
http://togetter.com/li/847799


shi3zさんの通信上の圧縮アルゴリズム利用の認識と、big_brosさんによる指摘及び圧縮アルゴリズムの解説 - Togetterまとめ
http://togetter.com/li/847777


ソフトバンクの「通信速度1位」のカラクリが明らかに、ヒントは「通信の最適化」 | BUZZAP!(バザップ!)
http://buzzap.jp/news/20140604-sbm-speed-network-optimize/


通信の最適化に関する回答(KDDI
https://www.evernote.com/shard/s12/sh/43e35fea-d581-45df-8025-87506ab27e83/6fb4e1214127812e


○個人的意見
個人的には重要な論点は3つ


1. 中間で圧縮することは有っても良いけど、方法がマズイ
HTTPのgzip圧縮とか標準仕様にしたがってやる分には、アプリのレイヤーに対して悪影響もないし問題ないけど、非可逆圧縮っていうのは無理筋
どうしてもやるなら、標準のパケット交換サービスに組み込むのではなく、オプションなり、安い別サービスなりにするべき。
サービスが土管やるなら良いけど、土管が勝手に余計なサービスするのは・・・・


2. 「通信の最適化」をやるなら、不動産などの契約における重要事項説明と同等のレベルで「明確な個別同意」をとるべき
これがきちんとしているならそもそも通信の秘密を犯すことにはならないはず。


3. 不可逆圧縮はどのレイヤーであっても勝手にやってはならない
サービス提供者の意図、あるいはユーザーの意図によってやる分にはレイヤーという意味ではアプリの層で圧縮することは正しい
・・・が、通信経路中のサービス提供者も、ユーザーも感知しないところで勝手にやるのはいけない
通信の当事者では無いキャリアが勝手にやることは通信の秘密を侵すいわゆる検閲でしかなく、正当業務行為としての違法性阻却事由にも合致しない


■各問題点についての整理


1. 品質劣化の問題


重要な論点はあまり無く、あまりに自明な問題なので詳細は省略


2. サービスへの干渉の問題


下記の案件で実際にサービスに悪影響発生しており、単なる懸念ではなく現実の問題となっている


スマホゲームの不具合、原因はソフトバンクの画像圧縮 ? すまほん!!
http://smhn.info/201506-softbank-assyuku?utm_source=dlvr.it&utm_medium=twitter


たとえば、アプリで利用するデータについてダウンロード後にCRCなどのハッシュによる破損、改変のチェックを行うようなアプリの場合、「通信の最適化」で非可逆圧縮された場合当然ハッシュも変わってしまうためエラーが発生する
上記のアプリの場合、まさにこのパターンで問題が起こっている


また、技術的な詳細が不明で適用条件が不明な点についても問題である


3. 通信の秘密への侵害の問題


まずはこちらを見てもらう


ソフトバンク、「通信の最適化」は『正当業務行為』。解除不可 - Engadget Japanese
http://japanese.engadget.com/2015/07/15/softbank/


ソフトバンクによると「通信の最適化」は「正当業務行為」とのことだが、この「正当業務行為」とはどういうことだろうか?
刑法では定められたいくつかの「違法性阻却事由」が定められている。
これは、たとえ違法な行為であっても、当該の違法性を否定する事由に合致する場合に例外的に違法行為であっても、違法性を否定するという「違法性阻却事由」に合致するため違法ではないというロジックである
これは「通信の秘密」に対しては「正当業務行為」「正当防衛」「緊急避難」の三つが適用できると想定されている。


しかし、なにが「正当業務行為」に該当するかについては 帯域制御の運用基準に関するガイドライン などで3つの要件が示されている


帯域制御の運用基準に関するガイドライン
http://www.jaipa.or.jp/other/bandwidth/


(1). 目的の正当性(帯域制御を実施する目的が ISP 等の業務内容に照らして正当なものであること)
(2). 行為の必要性(当該目的のために帯域制御を行う必要性があること)
(3). 手段の相当性(帯域制御の方法等が相当なものであること)


この全てに合致するかどうかは議論があり下記サイトなどが詳しい


ソフトバンクの「通信の最適化」の適法性ロジックを突き崩す方法。 ? すまほん!!
http://smhn.info/201507-softbank-tuusin-no-saitekika-ihou?utm_source=dlvr.it&utm_medium=twitter


なお、本来、ルータなど機械的な処理により、人の手による監視がない場合であっても通信の秘密を侵害したことには変わりはないとされている。
そのため、ISPの業務の多くは通信の秘密を侵害しているとされている。
ただし、「当事者の同意」がある場合、「正当業務行為」として「違法性阻却事由」に合致する場合のいずれかを満たすため業務を行うことが出来ている。


また、通信の秘密への侵害を回避する方法としてはもう一つユーザによる「当事者の同意」というものもある
こちらは、たとえばSPAMメールの隔離サービスなど、明らかに「通信の秘密」を犯す場合であっても、当事者の一方が「明確な同意」をしている場合には、同意に沿ってメールの中身を見ることができたりする。
ドコモとauはロジックとしてはこちらを採用しており、ユーザによる「個別かつ明確な同意」をとってあると強弁している。


しかし、「個別かつ明確な同意」というのはいわば重要事項説明のようなものであり、単に規約に書いてあるからOKといったものではないとされている。
いわば、「オプトイン」相当の意思の表示が必要とも・・・


4. ネットワーク中立性に反する問題


まとめ切れなかったので省略


5. 著作権の侵害の問題


同一性保持権著とは著作権における作者人格権の一種であり、著作物に対して著作者の意に反して変更、切除その他の改変を禁止することができる権利のことで、今回の「通信の最適化」においては、画像ファイルに対し非可逆圧縮を行いしかも品質の劣化が起こっているという時点で権利を侵していることはほぼ自明であるといって問題ないと思われる。
ただ、親告罪なので権利の主張をしなければ無視することも出来るし、仮に権利の主張をしたとしても裁判を経て権利を認めてもらう必要がありハードルが高い



6. その他


まとめ切れなかったので省略

HTTP 1.1 で 404応答などをした際、PHP の file_get_contents() の返りが遅い問題

詳しい調査はしていないが、HTTP 1.1 でサーバ側から自前でレスポンスを返した場合(200応答以外の404などのレスポンスのときに起きた)に、クライアント側の file_get_contents() の返りが遅いという問題が起こるようだ。
原因は HTTP 1.1 では KeepAliveがデフォルトで有効になるが、file_get_contents の側ではTCPコネクションのクローズまで待ってしまうことにあるようだ。

これは本来、リクエストしている file_get_contents の側で何とかするのが正しい対応かと思うが、どうも方法がよくわからない・・・

というわけでとりあえず、サーバー側で header('Connection: close'); として明示的にセッションのクローズを宣言することで回避できた。


後で調べたところ、サーバ側からレスポンスする HTTP のバージョンを 0.9 or 1.0 に下げることでも対応ができるらしい。
まあ、バージョンが下がればKeepAliveがデフォルトで無効になるということですね。


・・・ってことは、file_get_contents で使う HTTP コンテキストオプション の protocol_version を 1.1 にして投げればクライアント側で回避できるのかな?
そのうち気が向いたらテストしてみるか・・・


なお、PHPのバージョンは 5.3.10 とちと古いのでより新しいバージョンでは解消されてる可能性も・・・