Posts Tagged ‘fac2010’

    はてなブックマーク - サービスは止まっていないのにネットワークエラーが・・・なぜ?
    このエントリーをはてなブックマークに追加

    奥さまの名前は CentOS、旦那さまの名前はしんちゃん。
    ごく普通のサーバに、ごく普通にインストールし、ごく普通の納品をしました。
    でも、ただひとつ違っていたのは、ifconfig を叩くと………エラーが発生していたのです!

    *・゜゚・*:.。..。.:*・゜゚・*:.。. (n‘∀‘)η

    はじめての人もそうでない人もはじめまして。 河野と申します。

    Advent Calendar はスタートの火蓋が切られたばかりにも関わらず、私だけが二週目に突入しました。
    マッハ号もかくやといったところです。

    さて、本日は「サービスは止まっていないのにネットワークエラーが増え続ける」という奇妙な問題を解決した際のお話を皆様にしたいと思います。

    尚、サーバはCentOS となります。

    エラーの増加

    サンプルに偏りがあるのを承知で言いますが「サービスは止まっていないのにネットワークエラーが増え続ける」。
    そういった事象はあまり無いのではないかと思われます。
    ネットワークにエラーがある場合は、サービスどころかネットワーク自体が疎通出来なくなる事が多いのではないでしょうか?

    ところが今回のエラーは以下のような特徴を持っていました。

    • リモートからサーバへのアクセスが可能
    • ローカルから外部へのアクセスが可能
    • パケットのエラーが増え続ける

    エラー発生当初、サービスに支障が出ていないので、今後の経過を見るという判断になりました。

    このサーバには Munin というサーバ動作ログを視覚的に閲覧することの出来るソフトウェアをインストールしていたのですが、見るたびにサーバのエラーは増えていきました。

    # ifconfig
    eth0      Link encap:Ethernet  HWaddr 00:03:0D:34:8F:AD
              inet addr:10.1.0.1  Bcast:10.255.255.255  Mask:255.0.0.0
              inet6 addr: fe80::203:dff:fe34:8fad/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:5505120 errors:869 dropped:0 overruns:0 frame:869
              TX packets:563000 errors:0 dropped:0 overruns:0 carrier:0
              collisions:30 txqueuelen:1000
              RX bytes:900322789 (858.6 MiB)  TX bytes:102707436 (97.9 MiB)
              Interrupt:209 Base address:0xd800

    ※ ↑は執筆時に仮想サーバにてエラーを発生させてみたものです

    問題の調査

    色々と調査した結果、Auto-Negotiation 機能に問題があるのではないかという結論に至りました。

    ethtool コマンドで eth0 を調査した結果 half-duplex(半二重)になっていたからです。

    # ethtool eth0
    Settings for eth0:
            Supported ports: [ TP MII ]
            Supported link modes:   10baseT/Half 10baseT/Full
                                    100baseT/Half 100baseT/Full
            Supports auto-negotiation: Yes
            Advertised link modes:  10baseT/Half 10baseT/Full
                                    100baseT/Half 100baseT/Full
            Advertised auto-negotiation: No
            Speed: 100Mb/s
            Duplex: Half
            Port: MII
            PHYAD: 1
            Transceiver: internal
            Auto-negotiation: off
            Supports Wake-on: pg
            Wake-on: d
            Current message level: 0x000000c5 (197)
            Link detected: yes

    このサーバの eth1 はバックアップ装置と直繋ぎしておりこちらの通信モードは full-duplex(全二重)に設定されています。

    この結果から eth0 と繋がれているスイッチが full-duplex 固定に設定されており Auto-Negotiation 設定時に通信モードを返さなかった為、デフォルトの半2重設定を行ったと考えられました。

    問題の解決

    そうと分かればサーバ側の eth0 の設定を full-duplex 固定にしてしまえばいいだけの話です。

    ローカル環境で確認後、本番で行なった変更は ifcfg-eth0 の最後に以下の一文を加えるだけ。

    # vim /etc/sysconfig/network-scripts/ifcfg-eth0
    ETHTOOL_OPTS="autoneg off speed 100 duplex full"

    但し、ネットワークリスタートする必要があります。

    ちなみに eth-tool コマンドでも設定可能です。

    ● eth0 の autonegotiation を off

    # ethtool -s eth0 autoneg off

    ● eth0 の duplex を full にする

    # ethtool -s eth0 duplex full

    こちらは再起動を行なうと設定が消えますので、再起動後も設定を反映する場合は上記のようにデバイスの設定ファイルに設定を記述してください。

    最後に

    今回一番困ったのは「利用者からは問題がないように見える」点です。
    無視するわけにもいかないが、無視できる範囲のエラーなので、システムを停止することが難しいサーバや、社内システムだと止めるほどでも無いかもしれません。

    今回のエラーはサーバを設置してすぐだったため、トラフィックが増えてエラーが無視できなくなってくる前に対応する事にしました。

    どういったエラーでも対応すべきか、無視できるかは熟慮・検討する必要があるかと思いますが、今回のエラーは判断に迷う内容でした。

    結論からするとエラーは対応すべきものと私は思います。 が、技術的視点以外からの判断が加わってくると対応しないという結論もあるかもしれませんね。

      はてなブックマーク - jquery.simplesearch.js のご紹介
      このエントリーをはてなブックマークに追加

      はじめまして、同世代が次々と結婚していく現状にそろそろ焦りを感じ始めた島田です。
      (安元さんおめでとーございます!)

      Fusicでは主に、PHP, Javascript, サーバ構築・管理を担当しています。
      今後ともよろしくお願いします。

      早速ですが、今回は 自作 jQueryプラグイン の紹介をさせていただきます。

      内容

      このプラグインは、Firefoxの各種設定ページ(アドレスバーに about:config と入力した時に出てくるページ)のフィルタをイメージして作成しています。
      ※Ajax は使ってないです。

      [デモ]
      ※ デモのテキストボックスに『FW』と入力すると、Position が FW のリストだけが表示されます。

      行数の多いテーブルなどで、フィルタをかけて表示したい時などにご利用ください。
      デモでは、単純にHTMLのテーブルをフィルタリングしてますが、
      私はよく、環境変数や定数などを度忘れした時なんかに、print_a で表示してフィルタリングをかけたりしています。。

      使い方

      HTML:

      <!-- 検索用テキストボックス -->
      <p><input type="text" name="jquery.search" id="jquerysearch" value="" /></p>
      
      <hr />
      
      <!-- フィルタをかけるリスト -->
      <table id="seachtable">
        <thead>
          <tr>
            <th>No.</th>
            <th>Nationality.</th>
            <th>Position.</th>
            <th>Name.</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1</td>
            <td class="test">スペイン</td>
            <td>GK</td>
            <td>ビクトール・バルデス</td>
          </tr>
          <tr>
            <td>2</td>
            <td>ブラジル</td>
            <td>DF</td>
            <td>ダニエウ・アウヴェス</td>
          </tr>
          <tr>
            <td>3</td>
            <td>スペイン</td>
            <td>DF</td>
            <td>ジェラール・ピケ</td>
          </tr>
          <tr>
            <td>5</td>
            <td>スペイン</td>
            <td>DF</td>
            <td>カルレス・プジョル</td>
          </tr>
          <tr>
            <td>6</td>
            <td>スペイン</td>
            <td>MF</td>
            <td>シャビ</td>
          </tr>
          <tr>
            <td>7</td>
            <td>スペイン</td>
            <td>FW</td>
            <td>ダビド・ビジャ</td>
          </tr>
          <tr>
            <td>8</td>
            <td>スペイン</td>
            <td>MF</td>
            <td>アンドレス・イニエスタ</td>
          </tr>
          <tr>
            <td>9</td>
            <td>スペイン</td>
            <td>FW</td>
            <td>ボージャン・クルキッチ</td>
          </tr>
          <tr>
            <td>10</td>
            <td>アルゼンチン</td>
            <td>FW</td>
            <td>リオネル・メッシ</td>
          </tr>
          <tr>
            <td>11</td>
            <td>スペイン</td>
            <td>FW</td>
            <td>ジェフレン・スアレス</td>
          </tr>
          <tr>
            <td>13</td>
            <td>スペイン</td>
            <td>GK</td>
            <td>ホセ・マヌエル・ピント</td>
          </tr>
          <tr>
            <td>14</td>
            <td>アルゼンチン</td>
            <td>MF</td>
            <td>ハビエル・マスチェラーノ</td>
          </tr>
          <tr>
            <td>15</td>
            <td>マリ</td>
            <td>MF</td>
            <td>セイドゥ・ケイタ</td>
          </tr>
          <tr>
            <td>16</td>
            <td>スペイン</td>
            <td>MF</td>
            <td>セルヒオ・ブスケツ</td>
          </tr>
          <tr>
            <td>17</td>
            <td>スペイン</td>
            <td>FW</td>
            <td>ペドロ・ロドリゲス</td>
          </tr>
          <tr>
            <td>18</td>
            <td>アルゼンチン</td>
            <td>DF</td>
            <td>ガブリエル・ミリート</td>
          </tr>
          <tr>
            <td>19</td>
            <td>ブラジル</td>
            <td>DF</td>
            <td>マクスウェル</td>
          </tr>
          <tr>
            <td>21</td>
            <td>ブラジル</td>
            <td>DF</td>
            <td>アドリアーノ・コレイア</td>
          </tr>
          <tr>
            <td>22</td>
            <td>フランス</td>
            <td>DF</td>
            <td>エリック・アビダル</td>
          </tr>
          <tr>
            <td>26</td>
            <td>スペイン</td>
            <td>DF</td>
            <td>アンドレウ・フォンタス</td>
          </tr>
          <tr>
            <td>27</td>
            <td>スペイン</td>
            <td>FW</td>
            <td>ノリート</td>
          </tr>
          <tr>
            <td>28</td>
            <td>スペイン</td>
            <td>MF</td>
            <td>セルジ・ロベルト</td>
          </tr>
          <tr>
            <td>29</td>
            <td>スペイン</td>
            <td>FW</td>
            <td>ビクトール・バスケス</td>
          </tr>
          <tr>
            <td>30</td>
            <td>スペイン</td>
            <td>MF</td>
            <td>ティアゴ・アルカンタラ</td>
          </tr>
          <tr>
            <td>31</td>
            <td>スペイン</td>
            <td>GK</td>
            <td>ルベン・ミーニョ</td>
          </tr>
          <tr>
            <td>32</td>
            <td>スペイン</td>
            <td>DF</td>
            <td>マルク・バルトラ</td>
          </tr>
          <tr>
            <td>33</td>
            <td>スペイン</td>
            <td>DF</td>
            <td>セルジ・ゴメス</td>
          </tr>
          <tr>
            <td>34</td>
            <td>メキシコ</td>
            <td>MF</td>
            <td>ジョナタン・ドス・サントス</td>
          </tr>
          <tr>
            <td>35</td>
            <td>スペイン</td>
            <td>DF</td>
            <td>マルク・ムニエッサ</td>
          </tr>
          <tr>
            <td>36</td>
            <td>スペイン</td>
            <td>MF</td>
            <td>マルティ・リベロラ</td>
          </tr>
          <tr>
            <td>37</td>
            <td>スペイン</td>
            <td>MF</td>
            <td>オリオール・ロメウ</td>
          </tr>
          <tr>
            <td>38</td>
            <td>スペイン</td>
            <td>GK</td>
            <td>オイエル・オラサバル</td>
          </tr>
          <tr>
            <td>39</td>
            <td>スペイン</td>
            <td>FW</td>
            <td>ルベン・ロチーナ</td>
          </tr>
        </tbody>
      </table>

      Javascript:

      $(function(){
        $('#jquerysearch').simplesearch({
          // フィルタをかけた時、表示・非表示にするリスト
          lines: '#seachtable tbody tr',
          // 対象となる文字列が含まれるセレクタ
          //※nullの場合は、lines 全体の文字列を検索
          targets: 'td',
          // 最後の入力から interval秒 経過するとフィルタリングを開始します
          interval: 500
        });
      });
      

      DOMがロードされた時点(ready(fn))で、文字列・jQueryオブジェクトを変数に格納して、検索時にはその変数を参照するなどなるべくスムーズに動せるように実装しています。

      なお、ソースコードはここに置いてますので、ご自由にご利用ください。

      それでは、また次回お会いしましょう。
      さようなら。

      { 2010.12.5 }

      iPhone で暗号化

        はてなブックマーク - iPhone で暗号化
        このエントリーをはてなブックマークに追加

        初めまして、Fusic 河野です。
        わたくし、IT 系のバスケの社会人チームやiPhone アプリ系のコミュニティとかを
        やってたりするので、ご興味のある方はぜひご参加ください。

        弊社にはもう一人河野というものがおり、そっちとは違う方と
        覚えて頂けると溜飲が下がります。。。

        最近、プライベートではこんなことやってたりして遊んでます。
        Fusic では、主に ruby on rails をやっており、ZENPRE の iPhone アプリを
        担当させていただいてたりします。

        さて、昨日行われました安元の結婚式も無事に終わり、本日はとっても天気の良い日曜日です。
        それにしても、とても良い結婚式でした。

        「おめでとうございます。お二人とも末永くお幸せに!」

        で、そんな幸せに包まれつつな日曜日も Advent Calendar です。
        こんな日にバトンがまわってくるとは、、な気分ではございますがさっそく。

        ご結婚されたばかりのお二人には、なんとも、、な話かもしれませんが、
        いくら仲睦まじい関係だとしても、時には隠蔽する必要が出てくる事が
        あるやも知れません。
        そんな時に必要になってくること。

        “暗号化”についてです。

        前に山本が「as3cryptoで暗号化」 という記事を書いてますが、
        その記事の iPhone 版だと思っていただければ幸いです。

        暗号化

         objective-c で暗号化をする場合、CCCrypt() という関数を使います。

         [CCCrypt(3cc) Mac OS X Manual Page]
         developer.apple.com/library/mac/#DOCUMENTATION/Darwin/Reference/ManPages/man3/CCCrypt.3cc.html
         
         iPhone 用のサンプルコードはこちらになるのですが、見ていただくと分かるのですが、
         まー、as のように楽じゃないなというのが分かって頂けるかなと。

         CCCrypt() を使用して、NSData クラスに AES256EncryptWithKey, AES256DecryptWithKey のメソッドを追加します。
         (※ こちらを参考にしました)

         NSDataAdditions.m というファイルを作成し、以下を追加します。

        #import &lt;CommonCrypto/CommonCryptor.h&gt;
         
        @implementation NSData (Additions)
         
        @class NSString; 
         
        - (NSData *)AES256EncryptWithKey:(NSString *)key {
                char keyPtr[kCCKeySizeAES256+1];
                bzero(keyPtr, sizeof(keyPtr));
         
                [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
         
                NSUInteger dataLength = [self length];
         
                size_t bufferSize = dataLength + kCCBlockSizeAES128;
                void *buffer = malloc(bufferSize);
         
                size_t numBytesEncrypted = 0;
                CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,       
                                                                                 kCCOptionPKCS7Padding | kCCOptionECBMode,
                                                                                 keyPtr, kCCKeySizeAES256,
                                                                                 NULL,
                                                                                 [self bytes], dataLength,
                                                                                 buffer, bufferSize,
                                                                                 &numBytesEncrypted);
                if (cryptStatus == kCCSuccess) {
                        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
                }
                free(buffer);
                return nil;
        }
         
        - (NSData *)AES256DecryptWithKey:(NSString *)key {
                char keyPtr[kCCKeySizeAES256+1];
                bzero(keyPtr, sizeof(keyPtr));
         
                [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
         
                NSUInteger dataLength = [self length];
         
                size_t bufferSize = dataLength + kCCBlockSizeAES128;
                void *buffer = malloc(bufferSize);
         
                size_t numBytesDecrypted = 0;
                CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 
                                                                                 kCCOptionPKCS7Padding | kCCOptionECBMode,
                                                                                 keyPtr, kCCKeySizeAES256,
                                                                                 NULL,
                                                                                 [self bytes], dataLength,
                                                                                 buffer, bufferSize,
                                                                                 &numBytesDecrypted);
         
                if (cryptStatus == kCCSuccess) {
                        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
                }
                free(buffer);
                return nil;
        }
        @end

         使う側でファイルをインポートすれば、NSData クラスのメソッドとして使えます。

        base64encoding

         暗号化したデータを ZENPRE とかのように、サーバにデータを送る必要があるなら、
         base64 エンコードも実装する必要があります。
         同じく NSData クラスに newStringInBase64FromData というメソッドを追加します。
         (※ こちらを参考にしました)

         先程のファイルに下記を追加します。

        - (NSString *)newStringInBase64FromData {
                NSMutableString *dest = [[NSMutableString alloc] initWithString:@""];
                unsigned char * working = (unsigned char *)[self bytes];
                int srcLen = [self length];
         
                for (int i=0; i<srcLen; i += 3) {
                        for (int nib=0; nib<4; nib++) {
                            int byt = (nib == 0)?0:nib-1;
                                int ix = (nib+1)*2;
         
                                if (i+byt >= srcLen) break;
         
                                unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F);
         
                                if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F);
         
                                [dest appendFormat:@"%c", base64[curr]];
                        }
                }
                return dest;
        }

         同じく使う側でファイルをインポートすれば、NSData クラスのメソッドとして使えます。

        実行

         上記の追加したコードを含めたサンプルコードを実行します。

         

         入力した値が、base64 に変換されている事(真ん中のグレー領域)と
         暗号化されたものが復元されている事(下の白領域)を確認します。

        おわりに

         やはり、どうしても as と比べるとなんだかメンドクサイですね。
         暗号化の話は、コードも含め長文にどうしてもなってしまうので
         駆け足で進めていってしまいました。
         今回、objective-c の醍醐味の一つでもあるかなと個人的に思ってる、
         既存クラスへのメソッドの追加ができるってだけでも実感頂ければと思います。

         今回使用したサンプルのソースコードはココにあげております。
         お役に立てれば幸いです。

         それと、近々 ZENPRE の iPhone アプリの新版がリリースされる予定です。
         ご期待下さい。